2013-09-21 2 views
0

내 랜을 통해 내장 장치에 로그인하기 위해 데이터 바이트를 보내려고하지만 데이터를 보낼 때 TCP 스트림에 2 바이트가 추가됩니다.Java, tcp 출력의 원하지 않는 데이터는 어디서 오는가?

이 문제의 원인은 무엇입니까?

public class DeviceConnection { 

    Device dv; 
    Socket s; 
    PrintWriter out; 
    boolean connected = true; 

    public DvsConnection(Device d) { 
     try { 
      dv = d; 
      InetAddress addr = InetAddress.getByName(dv.IP_ADDRESS); 
      s = new Socket(addr, dv.ACTIVEX_PORT); 
     } catch (Exception ex) { 
      System.out.println(ex.toString()); 
      connected = false; 
     } 
     Connect(); 
    } 

    private void Connect() { 
     int[] headerStrt = {0x67, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 
     int[] usrName = convert.EncryptStr(15, dv.LOGIN, cypher); 
     int[] password = convert.EncryptStr(15, dv.PASSWORD, cypher); 
     int[] headerEnd = { 
      0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
      0x00, 0x00, 0x00, 0x00}; 
     int[] messageArray = convert.concatAll(headerStrt, usrName, spacer2, password, headerEnd); 
     try { 
      out = new PrintWriter(s.getOutputStream(), true); 
      byte[] sbytes=convert.IntArray2ByteArray(messageArray); 
      String message=convert.ByteArray2Ascii(sbytes); 
      out.println(message); 
      String hex = convert.ByteArray2Hex(sbytes); 
      System.out.println(hex); 
     } catch (Exception ex) { 
      System.out.println(ex.toString()); 
      connected = false; 
     } 
    } 


public class Convert { 

    public String ByteArray2Hex(byte[] a) { 
     StringBuilder sb = new StringBuilder(); 
     for (byte b : a) { 
      sb.append(String.format("%02x", b & 0xff)); 
     } 
     return sb.toString(); 
    } 

    public String ByteArray2Ascii(byte[] data) { 
     StringBuilder sb = new StringBuilder(data.length); 
     for (int i = 0; i < data.length; ++i) { 
      if (data[i] < 0) { 
       throw new IllegalArgumentException(); 
      } 
      sb.append((char) data[i]); 
     } 
     return sb.toString(); 
    } 

} 

콘솔 출력 :

6745000000000000000000004b4c4c29 
4d15176d0000000000000000005d4c57 
751653543b0808001c00000000001b00 
00000000000000000000000000000000 
00000000000000000000000000000000 
00000000000000000000000000000000 
00000000000000000000000000000000 

와이어 샤크 출력 :

00000000 67 45 00 00 00 00 00 00 00 00 00 00 4b 4c 4c 29 gE...... ....KLL) 
00000010 4d 15 17 6d 00 00 00 00 00 00 00 00 00 5d 4c 57 M..m.... .....]LW 
00000020 75 16 53 54 3b 08 08 00 1c 00 00 00 00 00 1b 00 u.ST;... ........ 
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........ 
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........ 
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........ 
00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........ 
00000070 0d 0a           .. 
+1

PrintWriter.println은 행의 끝에 캐리지 리턴/줄 바꿈 (0x0D 0x0A)을 추가합니다. –

+0

@AxelKemper 설명해 주면 어떻게 제거 할 수 있습니까? – andrew

+0

@andrew : 시작하는 데'println'을 사용하지 마십시오! 그러나 이상적으로는 이진 데이터에 대해 Writer를 사용하지 마십시오. –

답변

2

그것은 \r\n을 추가 println, 그러나 당신이 그 이상 여기에 근본적인 문제를 가지고있다. 바이너리 데이터를 텍스트처럼 취급합니다. 그 것입니다 조만간 물어보십시오.

이진 데이터로 작업하려는 경우 OutputStreamInputStream 하위 클래스 - WriterReader 하위 클래스가 아닌 하위 클래스를 사용하십시오. 이미 소켓에서 스트림을 얻고 있습니다. 왜 PrintWriterPrintReader에 포장하고 있습니까? 그것은 바로 으로 고쳐야하는 근본적인 실수입니다.

텍스트를 생각하지 않을 때 줄 바꿈 같은 것이 없기 때문에 더 이상 "줄 바꿈"데이터로 끝나지 않을 것입니다. 이에 대한 자세한 내용은 Marc Gravell's blog post on IO mistakes을 참조하십시오.

또한, 나는 강하게 조언 당신은 자바 명명 규칙을 다음 시작하는 것입니다 - 방법은 camelCased하지 PascalCased 있습니다. 실제 코드에서 예외 처리가 약간 다르기를 바랍니다.

관련 문제