私は個人的な学習目的でMUDサーバーを作成していますが、幸いなことに、ソケットのものをいくつかのクラスにまとめることができ、すべてが正しく機能しているように見えます。サーバーは接続をリッスンして受け入れ、現在クライアントからテキストを取得してすぐに送り返します。
問題は、WSAEWOULDBLOCK または有効なソケット以外の何かを返す accept() の呼び出しをどうするかよくわからないということです。新しいソケットを 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 からシングルトンとして派生します。
さらに情報が必要な場合はお知らせください。ご協力いただきありがとうございます。