该字节相当于切断套接字链接

时间:2016-09-28 10:43:28

标签: java sockets network-programming java-io

通常我使用

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");
        }
    }
}

在我执行finally之后,您会看到它始终进入7e块,此后它会切断链接。我想保持链接一段时间。但在此之前,我想在此场景中运行for循环来查找-1。我该如何实现呢?

1 个答案:

答案 0 :(得分:1)

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

如果您阅读文档,则说:

InputStream::read()

  

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

DataInputStream::readByte()

  

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

所有DataInputStream阅读方法都是如此。

因此,您所要做的就是正常读取DataInputStream中的值,如果套接字被对等关闭,则抛出异常。您已经完成了这项工作(EOFException扩展IOException并将在catch (IOException ex)块中捕获。你过分思考这个问题了。

话虽如此,如果读取0x7E字节抛出异常(readByte()调用失败?抛出哪个异常?),那么你做错了。例如,此问题基于code I gave you yesterday another question,但根据较早的代码,您在此问题中显示的代码不完整。遗漏很容易导致第二个if (r.readByte() != 0x7E)评估为假并关闭连接。

尝试更像这样的东西:

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();
}