我正在使用java服务器连接到带有安全websockets的浏览器。所有的连接都工作得很好,但很多时候我从socket.in.read(buffer,off,len)得到了意外的-1结果,这也发生在帧的中间。通常,我在收到-1时直接关闭套接字,因为它是流的末尾。然而,我注意到它也可能在连接重置时发生。我遇到过很多情况,在我的测试中,套接字在读取后返回有价值的数据,返回-1。我甚至有一种感觉,这种情况经常发生。在这种情况下,有时我只是从套接字中获取一些混乱的数据,我的问题就出现了。另一个问题是,当一个帧不能被传送时,另一端不会被通知...那么TCP/SSL有什么好处呢?如果你认为它是在java中传输websocket框架的不可靠连接?
我有一些方案可以用来处理不可靠的连接,以使shure数据包到达。但我希望有人知道在read返回-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;
}它仍然不是百分之百正确的,但至少我得到了比以前更可靠的结果。
发布于 2013-08-14 18:06:07
从socket.in.read(
,off,len)得到意外的-1结果
在调用此方法之前,您已经到达了EOS (流结束)。
这种情况也会发生在帧的中间。
在TCP中没有“帧”这样的东西。如果您的意思是它发生在应用程序消息的中间,那么您就遇到了应用程序协议错误。
通常我会在收到-1后直接关闭套接字,因为它是流的末尾。
对,是这样。
然而,我注意到它也可能在连接重置时发生
不,它没有。如果它有,你不可能检测到重置。这种说法是自相矛盾的。
我遇到过很多情况,在我的测试中,套接字在读取后返回有价值的数据,返回-1。
不,你没有。套接字在第一次返回-1之后,不能返回任何值。你根本得不到任何数据,更不用说“有价值的”数据了,除非你在某个地方忽略了-1。
当我有时只是在这种情况下从套接字中获取一些混乱的数据时,我的问题就出现了。
只有在忽略-1的情况下,才可以这样做。
另一个问题是,当帧不能被传送时,另一端不会被通知。
当然不是。如果你能向另一端发送通知,你就可以发送数据包。这也说不通。如果您的意思是,当另一端无法传递数据包时,它不会收到通知,那么您将面临TCP发送是异步的事实,因此您通常不会在导致它的发送上收到发送错误。您将在稍后的发送中获得它。如果您需要每次发送确认,则需要将它们构建到应用程序协议中。
那么TCP/SSL有什么好处呢?
TCP是可靠的数据流协议,SSL是安全可靠的数据流协议。这就是它们的用处。
如果你需要认为它是在java中传输websocket框架的不可靠连接?
他们都不是不可靠的。
我希望有人知道在
返回-1后该怎么做。
关闭插座。
同时,我做了更多的测试,发现如果你在收到-1之后继续阅读,它10次中有9次是有效的。
不,它不会。1000的1000倍,它继续返回-1。您在这里看到的是代码中其他bug的影响。
,所以即使你读了一半的帧并且收到了-1,你也应该以某种方式测试套接字是否关闭
你不能。插座没关。证明:你只是从中读取,而不会得到异常。您也不能测试连接是否关闭,除非通过read()返回-1。
我现在使用的是: socket.isInputShutdown()。
毫无意义。它会告诉您是否在自己的套接字上调用了Socket.shutdownInput()。它不会告诉你连接的状态。除了读取或写入之外,没有其他TCP API可以做到这一点。
如果不是这样,只需继续填充缓冲区即可。
例如,通过忽略read()返回的-1来读取gargabe。
为此,我现在使用以下代码,其中
是SSLSocket:
为什么?DataInputStream.readFully()已经存在了。重新实现它不会有什么帮助。
if(b < 0)
{
Logger.log(TAG, "readFully read returned: " + b + " testing if connection is reset or closed.", Logger.WARNING);
if(socket.isInputShutdown())在这一点上,你的Socket是否关闭输入是100%无关紧要的。read()返回-1,表示对端已关闭连接。句号。
{
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;
}在这里,您将0xff,为-1,的低位字节添加到缓冲区。这也是无稽之谈。
https://stackoverflow.com/questions/17130761
复制相似问题