关注处理接受错误的电话()

时间:2011-03-28 22:20:12

标签: c++ sockets network-programming winsock2 mud

我正在编写一个MUD服务器用于个人学习目的,我很高兴地设法将套接字包装成几个类,一切似乎都正常工作;服务器侦听并接受连接,并且当前从客户端获取文本并立即将其发送回来。

问题是我不太确定如何调用accept()返回WSAEWOULDBLOCK或有效套接字以外的东西。我是否只是将新套接字重置为0并返回,可能会显示一条错误消息,说明发生了什么错误?这就是我现在正在做的事情,如果它发生了20次我会关闭服务器。

void MUDControlSocket::Poll()
{
   // create a new connection here
   timeval timeout;

   FD_ZERO(&ReadSet);
   FD_ZERO(&WriteSet);
   FD_ZERO(&ExceptionSet);

   TopSocket = GetSocket();
   NewSocket = 0;
   FD_SET( GetSocket(), &ReadSet );

   if( SocketList.size() > 0 )
   {
      for( sockIter iter = SocketList.begin(); iter != SocketList.end(); ++iter )
      {
         FD_SET((*iter)->GetSocket(), &ReadSet);
         FD_SET((*iter)->GetSocket(), &WriteSet);
         FD_SET((*iter)->GetSocket(), &ExceptionSet);
         TopSocket = (*iter)->GetSocket();
      }
   }

   if( select( TopSocket+1, &ReadSet, &WriteSet, &ExceptionSet, &timeout ) == SOCKET_ERROR )
   {
      cout << "Error on select() call: " << SocketErrorType(WSAGetLastError()) << endl;

      delete this;
      exit(EXIT_FAILURE);
   }

   // as long as everything is working correctly, this if block should always be entered UNLESS a new connection is accepted
   if( (NewSocket = accept(GetSocket(), NULL, NULL) ) == INVALID_SOCKET )
   {
      if( WSAGetLastError() == WSAEWOULDBLOCK ) // it's not an actual problem. just nothing to connect to yet
         return;
      NewSocket = 0;
      static int count = 0;
      cout << "Error on accepting new connection: " << SocketErrorType(WSAGetLastError()) << endl;
      if( ++count >= 20 )
         done = true;
      return;
   }

   SocketList.push_back(new MUDSocket(NewSocket)); // only happens if accept DOES NOT return a value of INVALID_SOCKET i.e. a new connection was accepted
   TopSocket = NewSocket;
   NewSocket = 0;
}

TopSocket和NewSocket的类型为SOCKET,并在文件范围内声明。 SocketList是MUDSocket *的std :: list,MUDControlSocket是从MUDSocket派生为单例。

如果您需要更多信息并感谢您的帮助,请告诉我。

3 个答案:

答案 0 :(得分:0)

返回错误并让调用代码适当地处理它。

答案 1 :(得分:0)

接受的其他一些错误是内存不足,连接数量耗尽等等。

也许可以通过关闭未使用或遗忘的连接来处理,或者只是放弃并抛出异常。

答案 2 :(得分:0)

首先:不要将套接字设置为0:对于某些* NIX系统上的套接字来说,这是一个有效的fd,这是一个坏习惯。假设唯一无效的套接字fd是-1。做其他事情会在以后给你真正的软件带来真正的错误(相信我:我说的是从使用0作为无效套接字fd的经验调试代码)。

除此之外,我会说只是引发异常:accept不应该失败,除非你的资源耗尽,这应该是例外和错误。 C ++有一种处理这类事情的机制,这是例外。

BTW:delete this几乎总是一个非常糟糕的主意,在代码中间退出可能会使调试变得困难(抛出异常)并让调用者在需要时进行退出)和您可以使用accept来告诉您是否有任何要接受的内容,而不是尝试接受带有select的套接字 - 并将特殊情况处理移出函数,只在那里选择。你可以更进一步,实现一个专门的观察​​者模式(就像我在my podcast大约一个月前所做的那样),不仅要练习你的网络代码,还要练习你的设计模式。这也有助于使您的代码更具可移植性,并在以后可以重复使用。

HTH