1

recvループ内でデータを処理しているノンブロッキングの winsock ソケットがあります。

たとえば、パテと生のソケットに接続すると、メッセージの送信が正常に機能することに気付きました。MSG_PEEKただし、この特定のクライアントとインターフェイスする場合、パケットは への正常な非呼び出しをトリガーしていないように見えますrecv。数年前に同様の問題が発生したことを思い出し、 client でパケットを終了するか、 client\rからの何かを終了する必要がありました。この場合、クライアントを変更できないため、これは不可能です。

Wireshark は、パケットが問題なく通過することを示しています。しかし、私のサーバー プログラムは正しく動作していません。

どうすればこれを修正できますか?

編集:バッファー サイズをたとえば 8 に下げると、MSG_PEEK なしで recv の呼び出しがいくつか成功しました。

受信コール:

iLen = recv(group->clpClients[cell]->_sock, // I normally call without MSG_PEEK
        group->clpClients[cell]->_cBuff, CAPS_CLIENT_BUFFER_SIZE, MSG_PEEK);
if(iLen != SOCKET_ERROR)
{
    ...

ソケットは、AF_INETです。SOCK_STREAMIPPROTO_TCP

4

4 に答える 4

1

TRUEsetsockoptに設定するために使用します。TCP_NODELAY

于 2012-07-15T21:28:12.317 に答える
1

Microsoft のドキュメントには、MSG_PEEK非効率的で不正確なため、完全に避けるべきであるといくつかの場所で記載されています。select()WSAAsyncSelect()、またはを代わりに使用WSASelectEvent()して、ソケットに読み取り可能なデータがあることを検出し、 を呼び出しrecv()WSARecv()実際に読み取ります。

于 2012-06-29T19:46:42.337 に答える
0

ソリューションは実装固有のものになりました。クライアントから送信されるすべてのパケットの長さは、特定のバイト数で割り切れることがわかっています。そのため、バッファが空になるまでそのバイト数を読み取っただけです。

最大。この状況で一度に受信できるバイト数は、最長のメッセージの最大長よりも小さく、その長さの GCF (最大公約数) でなければなりません。

これは恒久的な解決にはほど遠いですが、今のところ機能しています。

于 2012-07-01T09:40:13.753 に答える
0

TCP ソケットはバイトストリームであり、アプリケーション メッセージの境界を保持しません。カーネルは、あなたに何かを与えるとすぐに、投票から戻ります。デコードする必要があるものをデコードするのに十分になるまで、受信したバイトを収集する必要があります。

于 2012-06-29T19:07:33.017 に答える