发送很多,我的send()调用导致我的程序完全停止。这怎么可能? [英] After sending a lot, my send() call causes my program to stall completely. How is this possible?

查看:256
本文介绍了发送很多,我的send()调用导致我的程序完全停止。这怎么可能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以基本上我是在C ++运行在linux上的MMO服务器。它工作正常,首先,但大约40秒后,50客户端,它会完全暂停。当我调试它,我发现基本上最后一帧,它在它停止响应之前是syscall()在这一点,它消失在内核中。一旦它消失在内核中,它甚至不会返回一个值...它完全令人不安。

So basically I'm making an MMO server in C++ that runs on linux. It works fine at first, but after maybe 40 seconds with 50 clients it will completely pause. When I debug it I find that basically the last frame its on before it stops responding is syscall() at which point it disappears into the kernel. Once it disappears into the kernel it never even returns a value... it's completely baffling.

50个客户端每250毫秒发送一个23字节。然后将这23个字节广播给所有其他49个客户端。此进程开始减慢,然后最终完全停止,其中内核从未从send()命令的系统调用返回。这里可能有什么原因?这真的推动我坚果!

The 50 clients are each sending 23 bytes every 250 milliseconds. These 23 bytes are then broadcasted to all the other 49 clients. This process begins to slow down and then eventually comes to a complete halt where the kernel never returns from a syscall for the send() command. What are some possible reasons here? This is truly driving me nuts!

我发现的一个选项是强制延迟的Nagles算法。我尝试切换它,但仍然会发生。

One option I found is Nagles algorithm which forces delays. I've tried toggling it but it still happens however.

编辑:程序被困在这里。具体来说,在send中调用syscall()

The program is stuck here. Specifically, in the send, which in turn calls syscall()

bool EpollManager::s_send(int curFD, unsigned char buf[], int bufLen, int flag) 
//     Meant to counteract partial sends
{
    int sendRetVal = 0;
    int bytesSent = 0;
    while(bytesSent != bufLen)
    {
 print_buffer(buf, bufLen);
        sendRetVal = send(curFD, buf + bytesSent, bufLen - bytesSent, flag); 

        cout << sendRetVal << " ";
        if(sendRetVal == -1)
        {
            perror("Sending failed");
            return false;
        }
        else
            bytesSent += sendRetVal;
    }
    return true;
}

这也是调用s_send的方法。

Also this is the method which calls the s_send.

    void EpollManager::broadcast(unsigned char msg[], int bytesRead, int sender)
    {
 for(iMap = connections.begin(); iMap != connections.end(); iMap++)
 {
  if(sender != iMap->first)
  {
   if(s_send(iMap->first, msg, bytesRead, 0)) // MSG_NOSIGNAL
   {
       if(debug)
       {
                    print_buffer(msg, bytesRead);
                    cout << "sent on file descriptor " << iMap->first << '\n';
       }
   }
  }
 }
 if(connections.find(sender) != connections.end())
        connections[sender]->reset_batch();
    }

并且澄清连接是boost的unordered_map的一个实例。程序阻塞的数据在任何方面都不是唯一的。

And to clarify connections is an instance of boost's unordered_map. The data that the program chokes on is not unique in any way either. It has been broadcast successfully to other file descriptors, but chokes on a, at least seemingly, random one.

推荐答案

内核保持不变,但是它已经成功地广播到其他文件描述符,但至少看起来似乎是随机的。用于发送数据的有限缓冲区。如果接收器没有接收,该缓冲器将填满,发送器将被阻塞。这是问题吗?

The kernel keeps a finite buffer for sending data. If the receiver isn't receiving, that buffer will fill up and the sender will block. Could that be the problem?

这篇关于发送很多,我的send()调用导致我的程序完全停止。这怎么可能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆