C套接字客户端/服务器滞后

我正在编写C / C ++客户端/服务器套接字应用程序。 此时,客户端每隔50ms将自身连接到服务器并发送消息。

一切似乎都有效,但数据流不是连续的:突然,服务器不再接收任何东西,然后一次收到5条消息……有时一切正常……

有人知道这种奇怪行为的起源吗?

代码的某些部分:

客户:

while (true) { if (SDL_GetTicks()-time>=50) { socket = new socket(); socket->write("blah"); message.clear(); message = socket->read(); socket->close(); delete socket; time=SDL_GetTicks(); } } 

服务器:

 while (true) { fd_set readfs; struct timeval timeout={0,0}; FD_ZERO(&readfs); FD_SET(sock, &readfs); select(sock + 1, &readfs, NULL, NULL, &timeout) if(FD_ISSET(sock, &readfs)) { SOCKADDR_IN csin; socklen_t crecsize = sizeof csin; SOCKET csock = accept(sock, (SOCKADDR *) &csin, &crecsize); sock_err = send(csock, buffer, 32, 0); closesocket(csock); } } 

编辑: 1。我试着做

 int flag = 1; setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof flag); 

在客户端和服务器中,但问题仍然存在。

那些连接/断开是非常有用的,但是当我尝试写的时候

 socket = new socket(); while (true) { if (SDL_GetTicks()-time>=50) { socket->write("blah"); message.clear(); message = socket->read(); time=SDL_GetTicks(); } } 

然后消息只发送一次(或收到)……

最后:

我忘了将TCP_NODELAY应用于服务器端的客户端套接字。 现在它完美无缺! 我将进程放在线程中,以便套接字保持打开状态。 谢谢你们 :)

这就是所谓的“ Nagle延迟 ”。 此算法正在等待TCP堆栈,以便在实际向网络发送任何内容之前到达更多数据,直到某些超时到期为止。 所以你应该修改Nagle超时( http://fourier.su/index.php?topic=249.0 )或者根本禁用Nagle延迟( http://www.unixguide.net/network/socketfaq/2.16.shtml ),所以每次send呼叫都会发送数据。

正如其他人已经回复的那样,你看到的延迟是由于TCP内置的Nagle算法 ,可以通过设置TCP_NODELAY套接字选项来禁用。

我想指出,由于持续的连接和断开连接,您的套接字通信效率非常低。 每次客户端连接到服务器时,都会发生三次握手 ,连接拆除需要四个数据包才能完成。 基本上你失去了TCP的大部分好处,但却带来了所有的缺点。

每个客户端维护与服务器的持久连接会更有效。 在Linux上select(2)甚至更好的epoll(4) ,或者在FreeBSD和Mac上选择kqueue(2) ,是在多个套接字上处理IO的非常方便的框架。

您可以使用TCP_NODELAY套接字选项立即强制发送数据。