2

私が作成した単純なクライアントサーバープログラムがありますが、主な問題は、クライアントとサーバーの間で接続が確立されると、クライアントがプログラムを閉じると、サーバーが最後のメッセージを繰り返し実行し、それが時々大きな問題を引き起こすことです。したがって、SOCKET 構造の状態を取得するために呼び出すことができる関数があれば、クライアントがプログラムを閉じると、サーバーは停止することがわかります。不良ソケットの関数から何を探すかが必要なだけです。ちなみに、私はこのプログラムを Win32 c で書いています。if(mySocket==SOCKET_ERROR) を試しましたが、うまくいかないようでした...間違って使用しない限り。ネットワーキングを始めたばかりです。

if(!sockServer.RecvData( recMessage, STRLEN )){return 0;}
// where
bool Socket::RecvData( char *buffer, int size )
{
    int i = recv( mySocket, buffer, size, 0 );
    if(!i){return false;}
    buffer[i] = '\0';
    return true;
}  //this isn't working
4

2 に答える 2

3

ピアがソケットを閉じるread()と、recv()ゼロが返されます。「サーバーが最後のメッセージを繰り返し実行する」場合、もちろん「時々」だけでなく常に「大きな問題を引き起こす」ことを無視している必要があります。

編集 1:また、別の基本的な TCP プログラミング エラーを作成しています: 1 回の読み取りでメッセージ全体を受信すると想定しています。TCP にはメッセージはなく、単なるバイト ストリームであり、書き込みと読み取りの間に 1::1 の対応はありません (send()およびrecv())。recv()ゼロまたはわずか 1 バイトを返すことができます。独自のメッセージ境界を編成する必要があり、処理できるメッセージ全体を受信するまでループする必要があります。

EDIT 2:また、受信メソッドのすべてのエラーを無視しています。-1`を返すことを探す必要がありrecv()、読み取ろうとしていたデータを処理するロジックを続行しないでください。少なくとも、perror() を呼び出すか、errno をチェックするか、Winsock に相当するものを確認する必要があります。

エラーまたは EOS が発生した場合は、ループを停止し、ソケットを閉じ、接続を忘れ、このクライアントを忘れる必要があります。

于 2012-10-16T23:31:52.817 に答える
1

メイン メッセージ プロシージャで FD_CLOSE をリッスンするのはどうですか? FD_CLOSE で WSAAsyncSelect を使用していますか?

于 2012-10-16T23:45:49.280 に答える