2015-05-08 113 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