Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 相当于切断套接字链接的字节_Java_Sockets_Network Programming_Java Io - Fatal编程技术网

Java 相当于切断套接字链接的字节

Java 相当于切断套接字链接的字节,java,sockets,network-programming,java-io,Java,Sockets,Network Programming,Java Io,通常当我使用 r = new BufferedReader(new InputStreamReader(receivedSocketConn1.getInputStream())); int nextChar = 0; while ((nextChar=r.read()) != -1) { } 然后我用 r = new BufferedReader(new InputStreamReader(receivedSocketConn1.getInputStream())); int

通常当我使用

r = new BufferedReader(new InputStreamReader(receivedSocketConn1.getInputStream()));
int nextChar = 0;
while ((nextChar=r.read()) != -1) 
{   

}
然后我用

r = new BufferedReader(new InputStreamReader(receivedSocketConn1.getInputStream()));
int nextChar = 0;
while ((nextChar=r.read()) != -1) 
{   

}
现在我将使用字节级

r = new DataInputStream(new BufferedInputStream(receivedSocketConn1.getInputStream()));
我读到的第一个字节是

try {
    while(true){
        if (r.readByte() != 0x7E) // start byte
        {
            // ah oh, something went wrong!!
            receivedSocketConn1.close();
            return;
        }

        int bodyLen = r.readUnsignedShort();       // message body nature (body length)

        byte serialNum1 = r.readByte();// message serial number
        byte[] messageBody = new byte[20];    // message body
        r.readFully(messageBody);

        if (r.readByte() != 0x7E) // end byte
        {
            // ah oh, something went wrong!!
            receivedSocketConn1.close();
            return;
        }
    }
}
catch (SocketTimeoutException ex)  
{ 
    System.out.println("SocketTimeoutException has been caught");
    ex.printStackTrace();
}  
catch (IOException ex)  
{ 
    System.out.println("IOException has been caught");
    ex.printStackTrace();
} 
finally
{
    try 
    {
        if ( w != null ) 
        {
            w.close();
            r.close();
            receivedSocketConn1.close();
        }
        else 
        {
            System.out.println("MyError:w is null in finally close");
        }
    }
}

在我执行
7e
之后,它总是进入
finally
块,然后它会切断链接。我想保留链接一段时间。但是在此之前,我想运行一个
for
循环,在这个场景中查找
-1
。如何实现它?

在这种情况下,您不需要处理
-1

如果您阅读文档,它会说:

返回:
数据的下一个字节,如果到达流的结尾,则为-1

抛出:
EOFEException-如果此输入流已到达末尾
IOException-流已关闭,并且包含的输入流在关闭后不支持读取,或者发生另一个I/O错误

所有
DataInputStream
读取方法也是如此

因此,您所要做的就是正常地从
DataInputStream
读取值,并在对等方关闭套接字时让它抛出异常。您已经在做这件事了(
eofeexception
extends
IOException
,并且将被捕获到
catch(IOException ex)
块中)。你对这个问题想得太多了

也就是说,如果读取
0x7E
字节引发异常(哪个
readByte()
调用失败?引发了哪个异常?),那么您就做错了。例如,此问题基于For,但您在此问题中显示的代码基于前面的代码是不完整的。如果(r.readByte()!=0x7E)计算为false并关闭连接,则该省略很容易导致第二个
if(r.readByte()!=0x7E)
计算为false

请尝试类似以下内容:

w = new DataOutputStream(new BufferedOutputStream(receivedSocketConn1.getOutputStream()));
r = new DataInputStream(new BufferedInputStream(receivedSocketConn1.getInputStream()));

try
{
    while(true)
    {
        if (r.readByte() != 0x7E) // start byte
            throw new RuntimeException("Incorrect start byte detected");

        int messageID = r.readUnsignedShort();     // message ID
        int bodyLen = r.readUnsignedShort();       // message body nature (body length)
        byte[] phoneNum = new byte[6];
        r.readFully(phoneNum);                     // device phone number
        int serialNum = r.readUnsignedShort();     // message serial number
        byte[] messageBody = new byte[bodyLen];    // message body
        r.readFully(messageBody);
        byte checkCode = r.readByte();             // check code

        if (r.readByte() != 0x7E) // end byte
            throw new RuntimeException("Incorrect end byte detected");

        // TODO: validate checkCode if needed...
        // ... 
        // if (checkCode is not valid)
        //    throw new RuntimeException("Bad checkCode value");

        // process message data as needed...
    }
}
catch (SocketTimeoutException ex)  
{ 
    System.out.println("SocketTimeoutException has been caught");
    ex.printStackTrace();
}  
catch (EOFException ex)  
{ 
    System.out.println("Socket has been closed");
}  
catch (IOException ex)  
{ 
    System.out.println("IOException has been caught");
    ex.printStackTrace();
} 
catch (RuntimeException ex)
{ 
    System.out.println(ex.getMessage());
    ex.printStackTrace();
} 
finally
{
    w.close();
    r.close();
    receivedSocketConn1.close();
}

您想在查找0x7E之前查找流的结尾吗?是的,在这个方法中我需要与-1等效的EJP?我需要从7E开始读到7E,这将是我的全部数据,但我需要保持链接。为什么这篇文章投了反对票?有什么错吗?我真的没有看到任何错误,我已经展示了我的努力,我已经做了什么,我在哪里被绊住了0x7E必须在事情的本质上,要么在流程结束之前到达,要么根本不到达。你所问的没有意义,也没有充分的动机。我看不出“维护链接”与此有什么关系。我要问的是是否有方法检查-1,就像我使用r=new BufferedReader(new InputStreamReader(receivedSocketConn1.getInputStream())时所做的那样;是的,我已经按照你的建议准备好了。是的,你是对的,我有点想太多了,把InputStream::read()搞混了。我还有一个问题,我是否需要设置此receivedSocketConn1.setSoTimeout(60000);对于此代码,或最终将关闭套接字?这取决于您希望接收消息的频率
setSoTimeout(60000)
将导致任何读取操作在1分钟内未收到字节时引发异常。在读取单个消息的两个
0x7E
字节之间,这将是一件好事,因为接收整个消息不需要1分钟。但是,如果一条新消息的发送时间超过1分钟,那么在不同消息之间这样做可能不是一件好事。我不太明白你的意思,“但是,如果一条新消息的发送时间超过1分钟,那么在不同消息之间这样做可能不是一件好事。”?想想看。如果将超时设置为1分钟,然后收到完整的消息,然后在2分钟内未发送另一条消息,则在发送第二条消息之前,您将收到超时错误。