我正在编写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();
}
}
Run Code Online (Sandbox Code Playgroud)
服务器:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
1.我试着做
int flag = 1;
setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof flag);
Run Code Online (Sandbox Code Playgroud)
在客户端和服务器上,但问题仍然存在.
那些连接/断开是非常有用的,但是当我试着写的时候
socket = new socket();
while (true)
{
if (SDL_GetTicks()-time>=50)
{
socket->write("blah");
message.clear();
message = socket->read();
time=SDL_GetTicks();
}
}
Run Code Online (Sandbox Code Playgroud)
然后消息只发送一次(或收到)......
最后:
我忘了将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的大部分好处,但却产生了所有的缺点.
这将是很多更高效地为每个客户端保持服务器持续连接.select(2)或者甚至更好,epoll(4)在Linux上,或kqueue(2)在FreeBSD和Mac上,是在多个套接字上处理IO的非常方便的框架.