0

iOS で掲示板システム (BBS) リーダーを作成しています。パケットの送受信を処理するために GCDAsyncSocket ライブラリを使用します。私が抱えている問題は、サーバーが送信するデータを常に複数のパケットに分割することです。didReceiveData() 関数で受信文字列を出力することで、それが起こることがわかります。

GCDAsyncSocket の readme から、TCP がストリームであることを理解しています。また、最後に二重の CR LF など、いくつかのエンド オブ ストリーム メカニズムがあることも知っています。WireShark を使用してパケットを解析しましたが、最後のデータ パケットに何らかのパターンの兆候はありません。このサイトは私が所有していないため、特定のバイトを送信できませんでした。最後のパケットを検出する方法が必要です。それ以外の場合、BBS クライアントはデータの表示をどのように処理しますか?

4

1 に答える 1

0

二重 CR LF はストリームの終わりではありません。たとえば、これは HTTP プロトコルの詳細の一部にすぎませんが、ストリームを閉じることとは関係ありません。HTTP 1.1 では、単一のストリームで複数の応答を送信できます。HTTP ヘッダーの後に二重の CR LF を付け、ストリームの終わりはありません。

TCP ソケット ストリームは、ブロックまたは非ブロックの反対側から閉じられている場合、読み取り時に 0 を返します。

したがって、送信が完了したときにサーバーがソケットを閉じると仮定すると、ループしてブロッキング読み取りを実行し、戻り値が > 0 の場合はデータを処理してから再度読み取ることができます。< 0 の場合、エラー コードを処理します (致命的であるかどうかにかかわらず)。 == 0 の場合、ソケットが反対側から閉じられている場合、再度読み取らないでください。

ノンブロッキング ソケットの場合、select() またはその他の API を使用して、ストリームがいつ読み取り可能になったかを検出できます。私はあなたが使用している特定のライブラリに精通していませんが、それが POSIX/Berkeley ソケット API であれば、そのように動作します。

いずれの場合も、処理の準備が整うまで、各読み取りの結果を連結して、入力のバッファーを構築する必要があります。おわかりのように、1 回の読み取りで完全なアプリケーション レベルのパケットが返されるとは限りません。しかし、あなたの質問に関しては、サーバーがソケットを閉じることを望んでいない限り、read が 0 を返すのを待つ必要があります。

于 2014-06-18T23:29:38.887 に答える