所以基本上我是用C++制作一个在Linux上运行的MMO服务器。一开始它可以正常工作,但是可能在40秒钟后,有50个客户端,它将完全暂停。当我调试它时,我发现基本上它停止响应之前打开的最后一帧是syscall(),此时它消失在内核中。一旦消失到内核中,它甚至不会返回任何值……这完全令人困惑。

50个客户端每250毫秒发送23个字节。然后,将这23个字节广播给所有其他49个客户端。此过程开始变慢,然后最终完全停止,在此内核永远不会从针对send()命令的系统调用返回。这里有什么可能的原因?这真让我发疯!

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

编辑:程序卡在这里。具体来说,在发送中,它依次调用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的方法。
    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的一个实例。程序阻塞的数据也不是唯一的。它已成功广播到其他文件描述符,但至少在一个看似随机的文件描述符上令人窒息。

最佳答案

内核为发送数据保留了一个有限的缓冲区。如果接收方没有接收到该缓冲区,则发送方将阻塞。可能是问题所在吗?

关于c++ - 发送很多之后,我的send()调用使我的程序完全停止。这怎么可能?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4568389/

10-11 22:50
查看更多