私はすでにソケット同期に関するこの質問を読んでいますが、まだ理解していません。
最近、TCP ソケットを介して通信が行われる比較的単純なクライアント/サーバー アプリに取り組んでいました。クライアントは C に似た関数 (特にfsockopen
およびfgetc
) を使用して PHP で記述され、PHP はソケットと対話するために提供します。サーバーは、Stream
データを出力するために を使用して node.js で記述されます。
プロトコルは非常に単純で、メッセージは 0 バイト文字で終わる単なる文字列です。
基本的には次のように機能します。
SERVER: Message 1
CLIENT: Ack 1
SERVER: Message 2
CLIENT: Ack 2
....
メッセージの終わりを示す 0 バイトが検出されるまで、ソケットから char ごとに char を読み取ることによって、クライアントが一度に 1 つのメッセージを処理したため、これは実際にうまく機能しました。次に、クライアントは、メッセージを正常に受信したことをサーバーに書き戻します (これがそのAck <message id>
部分です)。
今、これが起こりました:
SERVER: Message 1
CLIENT: Ack 1
SERVER: Message 2
CLIENT: Ack 2
SERVER: Message 3
Message 4
Message 5
Message 6
CLIENT: <DOH!>
....
stream.write(...)
つまり、サーバー上ではすべてのメッセージが単一の操作であるにもかかわらず、サーバーが予期せず 1 つの「バッチ」で複数のメッセージをクライアントに送信したことを意味します。メッセージがどこかにバッファリングされ、すぐにクライアントに送信されたようです。私のクライアントコードは、間に応答がなければソケット内の複数のメッセージを処理できAck
なかったため、id 3 の後に残りのメッセージを切り捨てました。
だから私の質問は:
- ソケットの読み取りと書き込みの同期はどの程度ですか? 上記の質問から、ソケットは基本的に 2 つの単方向パイプであることがわかりました。つまり、それらはまったく同期されていませんか?
- いくつかのメッセージが単純な「1 つのメッセージに 1 つの ACK」の方法でクライアントに送信された後、突然複数のメッセージがストリームに書き込まれる可能性はありますか?
- ソケットがブロッキング/ノンブロッキングの方法で開かれた場合、実際に画像が変わりますか?
PHP 5.4とノード0.6.xを使用して、これをUbuntu VMでテストしました(負荷がないか、奇妙な動作を引き起こす可能性があるものはありません)。