Java サーバーを使用して、安全な WebSocket を備えたブラウザーに接続しています。すべてが接続で正常に動作しますが、多くの場合、socket.in.read(buffer,off,len) から予期しない -1 の結果が返されます。これはフレームの途中でも発生します。通常、ストリームの終わりであるため、-1 を受信するとすぐにソケットを閉じます。ただし、接続のリセットでも発生する可能性があることに注意してください。私のテストでは、読み取り後に貴重なデータを返すソケットが -1 を返すという多くのケースに遭遇しました。私はこれが頻繁にあるとさえ感じています。私の問題は、そのような場合にソケットからスクランブルされたデータを取得することがある場合に発生します。もう 1 つの問題は、フレームが配信されない場合に相手側に通知されないことです... では、TCP/SSL の利点は何でしょうか? Javaでwebsocketフレームを転送するための信頼できない接続と考える必要がある場合?
パケットの到着を確実にするための信頼できない接続に対処するために使用するスキームがいくつかあります。しかし、読み取りが -1 を返した後に何をすべきかを誰かが知っていることを願っています。
この説明がやや曖昧で申し訳ありません... この問題の解決にうんざりしています。
ごみが入ってくる例 (JSON データを含むテキスト フレームのみが送信されます):
16-06-13 22:43:13.918;WebSocket;7: Read frame from websocket: 377, opcode:UNKNOWN
data: null
16-06-13 22:43:13.918;WebSocket;7: Read frame from websocket: 377, opcode:PONG_FRAME
data: null
16-06-13 22:43:13.918;WebSocket;7: Read frame from websocket: 377, opcode:TEXT_FRAME
data: =,6GiGGV7C6_TfPHg\~\c
これは、受信したフレームの別の例ですが、少し形式が正しくありません!? これは TCP/TLS 接続でどのように可能ですか???:
17-06-13 09:42:37.510;WebSocket;7: Read frame from websocket: 15, opcode:TEXT_FRAME
data: "kep-aiveY:"d613Nb2-N24eV463K-808-fJb30I9e3M02
{"keep-alive":"[UUID]"} と読むことになっています
一方、さらにテストを行ったところ、-1 を受信した後も読み続けると、10 回中 9 回は機能することがわかりました。したがって、フレームの途中まで読んで -1 を受け取ったとしても、ソケットが閉じているかどうかを何らかの方法でテストする必要があります。そうでない場合は、バッファをいっぱいにしていきます。そうするために、ソケットが SSLSocket である次のコードを使用します。
public static int readFully(Socket socket, InputStream is, byte[] buffer, int off, int len) throws IOException
{
int read = 0;
while(read < len)
{
int b = is.read();
if(b < 0)
{
Logger.log(TAG, "readFully read returned: " + b + " testing if connection is reset or closed.", Logger.WARNING);
if(socket.isInputShutdown())
{
throw new IOException("InputStream closed before data could be fully read! (readFully read returned -1 and socket.isInputShutdown() is true");
}
}
else
{
buffer[off + (read++)] = (byte) b;
}
}
return read;
}
まだ 100% 正しいわけではありませんが、少なくとも以前よりも信頼性の高い結果が得られます。