繁体   English   中英

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

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

我正在使用Java服务器通过安全的websocket连接到浏览器。 一切都与连接工作正常,但很多时候我从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次测试,发现有10次测试中有9次有效。 因此,即使您正在阅读框架的一半并且接收到-1,也应该以某种方式测试套接字是否关闭,我现在使用:socket.isInputShutdown()。 如果不是这种情况,则继续填充缓冲区。 为此,我现在使用以下代码,其中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;
}

它仍然不是百分百正确的,但是至少我得到了比以前更可靠的结果。

我从socket.in.read(buffer,off,len)中得到了意外的-1结果

在调用此方法之前,您已经达到EOS(流结束)。

这也发生在帧的中间。

TCP中没有“框架”之类的东西。 如果您是说它发生在应用程序消息的中间,则说明您存在应用程序协议错误。

通常我会在收到-1时直接关闭套接字,因为它是流的结尾。

正确。

但是我注意到它也可能在连接重置时发生

不,不是。 如果是这样,则可能无法检测到重置。 这种说法是自相矛盾的。

我遇到过很多情况,在我的测试中,套接字在读取返回-1后应该返回有价值的数据。

不,你没有。 套接字第一次返回后只能返回-1。 您根本无法获取任何数据,更不用说“有价值”的数据了,除非您忽略某个地方的-1。

当出现这种情况后,有时我只是从套接字中获取了一些加扰的数据时,我的问题就出现了。

仅当您忽略-1时,才这样做。

另一个问题是,当无法传递帧时,不会通知另一侧。

当然不是。 如果可以将通知传递到另一端,则可以传递数据包。 这也没有道理。 如果您的意思是当对方无法发送数据包时未收到通知, 说明TCP发送异步,因此通常不会在引起该错误的发送中收到发送错误。 您将在以后的发送中得到它。 如果需要按发送确认,则需要将它们内置到应用程序协议中。

那么,TCP / SSL有什么用呢?

TCP是可靠的数据流协议,而SSL是安全的可靠数据流协议。 那就是它们的用途。

如果您需要将其视为在Java中传输websocket框架的不可靠连接?

它们都不是不可靠的。

我希望有人知道读取后返回-1会做什么。

关闭插座。

值得一提的是,如果您在接收到-1后继续阅读,我会进行10次测试,发现有10次测试中有9次有效。

不,不是。 1000的1000倍,它继续返回-1。 您在这里看到的只是代码中其他错误的影响。

因此,即使您正在阅读框架的一半并且接收到-1,也应该以某种方式测试插座是否关闭

你不能 插座没有关闭。 证明:您只需阅读即可,无一例外。 除了通过read()返回-1之外,您无法测试连接是否也已关闭。

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

无意义。 这告诉你, 是否有人称Socket.shutdownInput()在自己的插座。 它不会告诉您有关连接状态的信息。 除了读取或写入外,没有任何TCP API可以做到这一点。

如果不是这种情况,则继续填充缓冲区。

即通过忽略read()返回的-1来read() Gargabe。

为此,我现在使用以下代码,其中socket是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;
}

在这里,您将-1,的低字节(即0xff,到缓冲区。 这也是胡说八道。

暂无
暂无

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

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