为什么当不止一次写入socket时,它会阻塞?

时间:2010-01-11 03:40:10

标签: c++ c sockets network-programming

我遇到插座问题,如果你能提供帮助,我会很高兴... 问题是,当我多次发送数据时,它会阻塞,例如:

//--- client ---  
//..
send(sock, buf_1, sizeof(buf_1), 0);  

for (x10){   
//...  
send(sock, buf_2, sizeof(buf_2), 0);    
if (recv(sock, buf_2, sizeof(buf_2), 0)<0) printf("recv_2() failed");   
//...   
}  

for (x20){   
//...  
send(sock, buf_3, sizeof(buf_3), 0);     
if (recv(sock, buf_3, sizeof(buf_3), 0)<0) printf("recv_3() failed");   
//...    
}  
//...          

//--- server---   
//...  
if (recv(sock, buf_1, sizeof(buf_1), 0)<0) printf("recv_1() failed"); 

for (x10){     
if (recv(sock, buf_2, sizeof(buf_2), 0)<0) printf("recv_2() failed");    
//...    
send(sock, buf_2, sizeof(buf_2), 0);     
}     

for (x20){   
if (recv(sock, buf_3, sizeof(buf_3), 0)<0) printf("recv_3() failed");   
//...    
send(sock, buf_3, sizeof(buf_3), 0);     
}     
//...   

交换阻止在第一个send()之后,有什么想法吗? udp是否也支持多个sendto()

感谢您的回答 -

2 个答案:

答案 0 :(得分:3)

在这种情况下,send和recv都是阻塞的。 您需要在套接字上设置异步标志(我认为是O_NONBLOCK - 请参阅fnctl的文档)。 但要想做到这一点,这可能很棘手。如果你不发送/获取所有数据,你必须继续调用send / recv,直到你得到所有数据,并且有效地执行此操作意味着你将不得不在套接字上使用select系统调用。

现在所有这些都是可行的,但调试并不是很有趣和痛苦。 我建议你尝试使用boost :: asio(异步io)库,而不是使用原始套接字。 http://www.boost.org/doc/libs/1_41_0/doc/html/boost_asio.html

答案 1 :(得分:1)

UDP还是TCP?

如果TCP;您发送的数据有多大。客户在做什么?客户端是否实际接收并处理第一个数据块?可能发生的事情是第二个发送调用是阻塞的,因为你的客户端的接收窗口已满并且TCP堆栈已经参与了流量控制,导致你的同步发送阻塞,等待对等体读取足够的数据,这样recv窗口就不会完全和流量控制情况已经过去了......

另请注意,如果您正在处理TCP,则recv调用CAN并且将返回1和您已发送的字节数之间的任意数量的字节;你应该总是循环以累积消息框架告诉你需要的字节数......

在你的问题的最后,你提到UDP和多个sendTos,这与你的问题有什么关系?事实上,你是否在这里使用UDP套接字?