简体   繁体   English

Java SSLSocket读取后返回-1怎么办?

[英]Java SSLSocket what to do after read returns -1?

I'm using a java server to connect to a browser with secure websockets. 我正在使用Java服务器通过安全的websocket连接到浏览器。 All works fine with the connect, but many times i get an unexpected -1 result from socket.in.read(buffer,off,len), this happens also in the middle of a frame. 一切都与连接工作正常,但很多时候我从socket.in.read(buffer,off,len)中得到了意外的-1结果,这种情况也在帧的中间发生。 Normally i close a socket directly upon reception of -1, since it is end of stream. 通常我会在收到-1时直接关闭套接字,因为它是流的结尾。 However i noted that it can also happen on a connection reset. 但是我注意到它也可能在连接重置时发生。 I have come over many cases where in my tests the socket whould return valuable data after read returned -1. 我遇到过很多情况,在我的测试中,套接字在读取返回-1后应该返回有价值的数据。 I even have the feeling this is more often than not. 我什至感觉这种情况经常发生。 My problem arrises when sometimes i just get some scrambled data out of the socket after such a case. 当出现这种情况后,有时我只是从套接字中获取了一些加扰的数据时,我的问题就出现了。 Another problem is that the other side is not notified when a frame cannot be delivered... So what good is TCP/SSL than? 另一个问题是,当无法传递帧时,不会通知另一端...那么,TCP / SSL有什么用呢? if you need to consider it an unreliable connection for transporting websocket frames in java? 如果您需要将其视为在Java中传输websocket框架的不可靠连接?

I have some schemes to use that are used to deal with unreliable connections for making shure a packet arrives. 我有一些方案可以用来处理不可靠的连接,以确保数据包到达。 But i hope that somebody knows what to do after read returns -1. 但我希望有人知道读取后返回-1会做什么。

Sorry for the somewhat vague description in this one... i'm getting tired with solving this issue. 抱歉,在此文章中有些含糊的描述...我对解决此问题感到厌倦。

Just an example of some rubbish comming in (only text frames are submitted containing JSON data): 这只是一些垃圾的例子(仅提交包含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

Here another example of a received frame that is just a bit malformed!? 在这里,接收到的帧的另一个示例只是格式不正确! how is this possible with a TCP/TLS connection???: 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

It is supposed to read {"keep-alive":"[UUID]"} 应该读取{“ keep-alive”:“ [UUID]”}

Meanwhilst i have done some more testing and found that 9 out of 10 times it works if you continue reading after reception of -1. 值得一提的是,如果您在接收到-1后继续阅读,我会进行10次测试,发现有10次测试中有9次有效。 So even if you are reading halfway the frame and receive a -1 then you should test somehow if the socket is closed or not, i now use: socket.isInputShutdown(). 因此,即使您正在阅读框架的一半并且接收到-1,也应该以某种方式测试套接字是否关闭,我现在使用:socket.isInputShutdown()。 if this is not the case then just continue filling up the buffer. 如果不是这种情况,则继续填充缓冲区。 To do so i now use the following code where socket is the SSLSocket: 为此,我现在使用以下代码,其中socket是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;
}

It is still not a hundred % correct but at leas i get more reliable results then before. 它仍然不是百分百正确的,但是至少我得到了比以前更可靠的结果。

i get an unexpected -1 result from socket.in.read(buffer,off,len) 我从socket.in.read(buffer,off,len)中得到了意外的-1结果

You have already reached EOS (end of stream) before you called this method. 在调用此方法之前,您已经达到EOS(流结束)。

this happens also in the middle of a frame. 这也发生在帧的中间。

There is no such thing as a 'frame' in TCP. TCP中没有“框架”之类的东西。 If you mean it happens in the middle of an application message, you have an application protocol error. 如果您是说它发生在应用程序消息的中间,则说明您存在应用程序协议错误。

Normally i close a socket directly upon reception of -1, since it is end of stream. 通常我会在收到-1时直接关闭套接字,因为它是流的结尾。

Correct. 正确。

However i noted that it can also happen on a connection reset 但是我注意到它也可能在连接重置时发生

No it doesn't. 不,不是。 If it did, you could not possibly have detected the reset. 如果是这样,则可能无法检测到重置。 The statement is self-contradictory. 这种说法是自相矛盾的。

I have come over many cases where in my tests the socket whould return valuable data after read returned -1. 我遇到过很多情况,在我的测试中,套接字在读取返回-1后应该返回有价值的数据。

No you haven't. 不,你没有。 A socket can't return anything but -1 after it first does so. 套接字第一次返回后只能返回-1。 You can't be getting any data at all, let alone 'valuable' data, unless you are ignoring the -1 somewhere. 您根本无法获取任何数据,更不用说“有价值”的数据了,除非您忽略某个地方的-1。

My problem arrises when sometimes i just get some scrambled data out of the socket after such a case. 当出现这种情况后,有时我只是从套接字中获取了一些加扰的数据时,我的问题就出现了。

Only if you ignore the -1, as you are doing. 仅当您忽略-1时,才这样做。

Another problem is that the other side is not notified when a frame cannot be delivered. 另一个问题是,当无法传递帧时,不会通知另一侧。

Of course it isn't. 当然不是。 If you could deliver a notification to the other side, you could deliver the packet. 如果可以将通知传递到另一端,则可以传递数据包。 This doesn't make sense either. 这也没有道理。 If you mean that the other side doesn't get notified when it couldn't deliver the packet, you are up against the fact that TCP sends are asyncrhonous, so you won't normally get a send error on the send that caused it. 如果您的意思是当对方无法发送数据包时未收到通知, 说明TCP发送异步,因此通常不会在引起该错误的发送中收到发送错误。 You will get it on a later send. 您将在以后的发送中得到它。 If you need per-send acknowledgements, you need to build them into your application protocol. 如果需要按发送确认,则需要将它们内置到应用程序协议中。

So what good is TCP/SSL then? 那么,TCP / SSL有什么用呢?

TCP is a reliable data-stream protocol, and SSL is a secure reliable data-stream protocol. TCP是可靠的数据流协议,而SSL是安全的可靠数据流协议。 That's what use they are. 那就是它们的用途。

if you need to consider it an unreliable connection for transporting websocket frames in java? 如果您需要将其视为在Java中传输websocket框架的不可靠连接?

Neither of them is unreliable. 它们都不是不可靠的。

I hope that somebody knows what to do after read returns -1. 我希望有人知道读取后返回-1会做什么。

Close the socket. 关闭插座。

Meanwhilst i have done some more testing and found that 9 out of 10 times it works if you continue reading after reception of -1. 值得一提的是,如果您在接收到-1后继续阅读,我会进行10次测试,发现有10次测试中有9次有效。

No it doesn't. 不,不是。 1000 times of 1000 it continues to return -1. 1000的1000倍,它继续返回-1。 All you are seeing here is the effect of other bugs in your code. 您在这里看到的只是代码中其他错误的影响。

So even if you are reading halfway the frame and receive a -1 then you should test somehow if the socket is closed or not 因此,即使您正在阅读框架的一半并且接收到-1,也应该以某种方式测试插座是否关闭

You can't. 你不能 The socket isn't closed. 插座没有关闭。 Proof: you just read from it without getting an exception. 证明:您只需阅读即可,无一例外。 You can't test whether the connection is closed either, other than by read() returning -1. 除了通过read()返回-1之外,您无法测试连接是否也已关闭。

I now use: socket.isInputShutdown(). 我现在使用:socket.isInputShutdown()。

Pointless. 无意义。 That tells you whether you have called Socket.shutdownInput() on your own socket. 这告诉你, 是否有人称Socket.shutdownInput()在自己的插座。 It doesn't tell you diddly-squat about the state of the connection. 它不会告诉您有关连接状态的信息。 There is no TCP API that can do that, other than reading or writing. 除了读取或写入外,没有任何TCP API可以做到这一点。

if this is not the case then just continue filling up the buffer. 如果不是这种情况,则继续填充缓冲区。

Ie reading gargabe by ignoring the -1 that read() is returning. 即通过忽略read()返回的-1来read() Gargabe。

To do so i now use the following code where socket is the SSLSocket: 为此,我现在使用以下代码,其中socket是SSLSocket:

Why? 为什么? DataInputStream.readFully() already exists. DataInputStream.readFully()已存在。 Re-implementing it won't help. 重新实现它没有帮助。

if(b < 0)
{
    Logger.log(TAG, "readFully read returned: " + b + " testing if connection is reset or closed.", Logger.WARNING);
    if(socket.isInputShutdown())

At this point it is 100% irrelevant whether your Socket is shutdown for input. 在这一点上,是否为输入关闭Socket是100%无关紧要的。 read() has returned -1, which means the peer has closed the connection. read()返回-1,这意味着对等方已关闭连接。 Period. 期。

    {
        throw new IOException("InputStream closed before data could be fully read! (readFully read returned -1 and socket.isInputShutdown() is true");
    }

This is all nonsense. 这全是废话。

}
else
{
    buffer[off + (read++)] = (byte) b;
}

Here you are adding the low byte of -1, which is 0xff, to the buffer. 在这里,您将-1,的低字节(即0xff,到缓冲区。 This is also nonsense. 这也是胡说八道。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM