所以基本上我是用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/