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

时间:2010-02-27 19:00:04

标签: c sockets

我正在编写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);

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

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

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

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

最后:

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

3 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:5)

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

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

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

答案 2 :(得分:3)

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