编程语言
首页 > 编程语言> > c-发送大量内容后,我的send()调用使我的程序完全停止.这怎么可能?

c-发送大量内容后,我的send()调用使我的程序完全停止.这怎么可能?

作者:互联网

所以基本上我是用C制作一个在Linux上运行的MMO服务器.起初它可以正常工作,但在50个客户端的40秒后,它将完全暂停.当我调试它时,我发现基本上它停止响应之前打开的最后一帧是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的一个实例.程序阻塞的数据也不是唯一的.它已经成功地广播到其他文件描述符,但是至少在一个看似随机的文件描述符上令人窒息.

解决方法:

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

标签:send,tcp,linux-kernel,linux,c-4
来源: https://codeday.me/bug/20191208/2094629.html