2016-09-28 7 views
-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"); 
     } 
    } 
} 

Вы видите, что он всегда идет в блок finally после того, как я делаю 7e, после чего он разрезает ссылку. Я хотел бы сохранить ссылку в течение некоторого времени. Но до этого я хочу запустить цикл for для поиска -1 в этом сценарии. Как это реализовать?

+0

Вы хотите посмотреть на конец потока * до * ищет 0x7E? – EJP

+0

Да EJP Мне нужен эквивалент -1 в этом методе?Мне нужно начать чтение с 7Е до 7Е, что будет моими полными данными, но мне нужно поддерживать ссылку. – user5313398

+0

Почему этот пост голосует, что в этом плохого? Я действительно не вижу никакой ошибки, я показал свое усилие, что я сделал, и где я застрял – user5313398

ответ

1

В этой ситуации не нужно обрабатывать -1.

Если вы читали документацию, он говорит:

InputStream::read()

Возвращает:
следующий байт данных, или -1, если конец потока достигается.

DataInputStream::readByte()

Выдает:
EOFException - если этот входной поток достиг конца.
IOException - поток был закрыт, а входящий поток не поддерживает чтение после закрытия или возникла другая ошибка ввода-вывода.

То же самое касается всех методов чтения DataInputStream.

Итак, все, что вам нужно сделать, это прочитать значения из DataInputStream и дать ему исключение, если сокет будет закрыт одноранговым узлом. Вы уже делаете именно то, что (расширяет 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(); 
} 
+0

Да, я поставил (правда) готово, как ваше предложение. Да, вы правы. Я немного передумал и перепутался с InputStream :: read(). Еще один вопрос, который у меня есть, мне нужно настроить этот gotSocketConn1.setSoTimeout (60000); для этих кодов или в конечном итоге сокет будет закрыт? – user5313398

+0

Это зависит от того, как часто вы ожидаете получать сообщения. 'setSoTimeout (60000)' заставит любую операцию чтения генерировать исключение, если никакие байты не принимаются в течение 1 минуты. Было бы хорошо сделать это между чтением двух байтов «0x7E» одного сообщения, так как для получения всего сообщения не требуется 1 минута. Но это может быть нехорошо делать между различными сообщениями, если требуется более 1 минуты для отправки нового сообщения. –

+0

Я не совсем понимаю вас здесь. «Но это может быть нехорошо делать между разными сообщениями, если для отправки нового сообщения требуется более 1 минуты».? – user5313398