我正在使用 java 服务器连接到具有安全 websockets 的浏览器。连接一切正常,但很多时候我从 socket.in.read(buffer,off,len) 得到一个意外的-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,那么您应该以某种方式测试套接字是否关闭,我现在使用:socket.isInputShutdown()。如果不是这种情况,则继续填充缓冲区。为此,我现在使用以下代码,其中套接字是 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;
}
它仍然不是百分百正确,但至少我得到了比以前更可靠的结果。