2015-05-08 55 views
1

希望有人能幫助我。我想實現某種超時,如果我的套接字無法在一定的時間內接收數據...我在網上查找方式,但我看過的例子沒有他們的recv( )在像我這樣的while循環中,他們通常只是接收等待的整個緩衝區。也許我的效率不高,有人可能會指出我在接收所有數據方面有更好的方向。帶超時的C/C++ recv()

要接收的字符串不是固定長度,這就是爲什麼我一次收到1個字符串,因爲我不知道字符串有多大。正如你可以看到我的recv()將接收數據,直到它找到文本字符結尾()。我發現select()的例子會在調用receive之前使用select,但是我應該如何爲while循環的每一個循環執行該操作?或者甚至在我輸入while循環之前調用select()?

無論如何,任何幫助表示讚賞。

string recv_data(int socket){ 

bool endfound = false; 
char temp[1]; 
string recvstring ; 
while(endfound == false)//receives 1 character at a time until ETX(\x03)character is found 
{ 
    if(recv(socket,temp,sizeof(temp),0)<0) 
    { 
     perror("error in recv data"); 
    } 

    if(memchr(temp,'\x03',1) != NULL) 
    { 
     endfound = true; 
    } 

    recvstring += temp; 
    temp[0] = 0; 
} 

return formatting(recvstring); 
} 
+0

有了這個:'recvstring + = temp;'你的意思是'recvstring + = temp [0];'? (否則它會去查找空終止符) – Galik

+1

如果您的平臺支持它,您可以使用SO_RCVTIMEO,但我同意您的看法,即整個設計是錯誤的。網絡代碼中不需要一次讀取一個字節。 – EJP

+0

我剛開始感覺到,因爲我不知道輸入字符串的大小,所以最好在收到字符串之前找到結尾。現在想想看,我可能會很好,只需將我的char聲明爲一個大的東西,然後搜索結尾的文本字符以添加一個空終止符。 – Zack

回答

0

您必須將您的套接字置於非阻塞模式,並使用poll()。 poll()技術上也適用於常規阻塞套接字;然而,根據我的經驗,在語義和競爭條件中存在各種細微差別時,在使用poll()和阻塞套接字時,爲了獲得最佳可移植性,我總是使用非阻塞模式套接字以及poll(),並仔細檢查從recv()或read()返回值。

一些谷歌食物給你:fcntl(),F_SETFL,O_NONBLOCK

+1

你*可以*不是'必須的'。還有其他解決方案。 – EJP

+0

儘管如此,將套接字的非阻塞模式與poll()(或者select())結合起來,可能是最強烈的_portable_方法來強制執行接收超時。 –

+0

我從來沒有聽說過poll()。我會研究一下。這可能對我正在做的事更好。謝謝。 – Zack