首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java在SSLSocket返回-1后怎么办?

Java在SSLSocket返回-1后怎么办?
EN

Stack Overflow用户
提问于 2013-06-16 14:23:37
回答 1查看 568关注 0票数 0

我正在使用java服务器连接到带有安全websockets的浏览器。所有的连接都工作得很好,但很多时候我从socket.in.read(buffer,off,len)得到了意外的-1结果,这也发生在帧的中间。通常,我在收到-1时直接关闭套接字,因为它是流的末尾。然而,我注意到它也可能在连接重置时发生。我遇到过很多情况,在我的测试中,套接字在读取后返回有价值的数据,返回-1。我甚至有一种感觉,这种情况经常发生。在这种情况下,有时我只是从套接字中获取一些混乱的数据,我的问题就出现了。另一个问题是,当一个帧不能被传送时,另一端不会被通知...那么TCP/SSL有什么好处呢?如果你认为它是在java中传输websocket框架的不可靠连接?

我有一些方案可以用来处理不可靠的连接,以使shure数据包到达。但我希望有人知道在read返回-1后该怎么做。

很抱歉在这篇文章中有些含糊的描述...我已经厌倦了解决这个问题。

这只是一些垃圾的例子(只提交包含JSON数据的文本框架):

代码语言:javascript
复制
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连接是如何实现的?:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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;
}

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

EN

回答 1

Stack Overflow用户

发布于 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()已经存在了。重新实现它不会有什么帮助。

代码语言:javascript
复制
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,表示对端已关闭连接。句号。

代码语言:javascript
复制
    {
        throw new IOException("InputStream closed before data could be fully read! (readFully read returned -1 and socket.isInputShutdown() is true");
    }

这都是胡说八道。

代码语言:javascript
复制
}
else
{
    buffer[off + (read++)] = (byte) b;
}

在这里,您将0xff,-1,的低位字节添加到缓冲区。这也是无稽之谈。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17130761

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档