2012-12-26 84 views
5

是否有超時的跨平臺使用soulution功能accept沒有設置套接字非阻塞接受客戶端?如何接受超時插座

我知道,我應該使用select功能,但我在做什麼錯?

SOCKET NativesAcceptClient(SOCKET s, int timeout) 
{ 
    int iResult; 
    struct timeval tv; 
    fd_set rfds; 
    FD_ZERO(&rfds); 
    FD_SET(s, &rfds); 

    tv.tv_sec = (long)timeout; 
    tv.tv_usec = 0; 

    iResult = select(s, &rfds, (fd_set *) 0, (fd_set *) 0, &tv); 
    if(iResult > 0) 
    { 
     return accept(s, NULL, NULL); 
    } 
    else 
    { 
    //always here, even if i connect from another application 
    } 
    return 0; 
} 

如何解決這個問題? 謝謝!

+0

@ryanbwork不,超時是10 – Boris

+0

請參閱下面的解決方案? – ryanbwork

+1

是否立即彈出選擇或等待10s彈出之前(如果你不連接到它)?它看起來沒問題(除了提到的非Windows平臺的s + 1),其他的東西是不對的... – mark

回答

2

select調用的第一個參數應該等於fd_set集合中最大的文件描述符加1(請參閱here)。嘗試將第一個參數更改爲s+1;當您的套件中有多個套接字時,您將需要添加一些邏輯。

+0

謝謝,但我現在正在Windows上測試,因爲我知道第一個參數在窗口上被忽略 – Boris

+0

您能否確保您的傳入連接在您的10秒窗口內進行? – ryanbwork

0

select()的第一個參數是至少比任何位集中的文件描述符的最大值大1 的int。在這種情況下,

iResult = select(s + 1, &rfds, (fd_set *) 0, (fd_set *) 0, &tv); 

應該工作。

1

select()返回> 0如果一個插座用信號,0上超時,和-1。 select()實際回報給你什麼值?你只是檢查> 0和< = 0,這意味着你不區分-1和0.如果它返回0,那麼沒有客戶端連接到你的套接字,但如果它返回-1,那麼你的套接字可能無效開始。