2013-08-21 4 views
0

나는 바퀴를 재발 명하고 내 자신의 websocket 서버를 만들려고 노력하고있다. 구글 크롬과 파이어 폭스 모두에서 잘 연결되어 있으며 최대 127 글자의 텍스트 프레임을 정확하게 수신하고 에코합니다. 그러나, 구글은 나에게 다음과 같은 오류 제공을 넘어 님의길이가 128 자 이상인 Java Websocket Text Frame 오류?

웹 소켓 연결 'WS를 : // localhost를 : 9999 /'실패 바이트의 최소 숫자는 길이를 인코딩하는 데 사용되어야한다

파이어 폭스 받게됩니다/처음 몇 문자를 해석 한 다음 실패한 코드 : 1006.

서버가 메시지를 완전히 수신 중이고 런타임 오류없이 전체를 브로드 캐스트하려고 시도하는 것으로 나타납니다. 그것은 또한 내 System.out.println()에 표시된 것처럼 16 비트 길이 생성자로 이동합니다. 서버에서 내 자바 콘솔을 읽

웹 소켓 서버는 클라이언트가 메시지가 수신 연결을 시작 1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij12345678 방송 : 1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij12345678 2 데이터

나는 현재 내가 함께 보내고있다 프레임을 테스트하기 위해 프레임 테스터를 쓰고 있어요 지역 사회가 저에게 다리 작업의 일부를 구할 수 있기를 희망했습니다. 정말 이상한 점은 길이가 2 바이트 인 126과 127 페이로드 길이가 작동하고 반영한다는 것입니다.

public void broadcast(String mess) throws IOException { 
     System.out.println("broadcasting: "+mess); 
     byte[] rawData = mess.getBytes(); 

     int frameCount = 0; 
     byte[] frame = new byte[10]; 

     frame[0] = (byte) 129; 

     if (rawData.length <= 125) { 
      frame[1] = (byte) rawData.length; 
      frameCount = 2; 
     } else if (rawData.length >= 126 && rawData.length <= 65535) { 
      System.out.println("2nd data"); 
      frame[1] = (byte) 126; 
      byte len = (byte) rawData.length; 
      frame[2] = (byte) ((len >> 8) & (byte) 255); 
      frame[3] = (byte) (len & (byte) 255);     
      frameCount = 4; 
     } else { 
      System.out.println("3rd data"); 
      frame[1] = (byte) 127; 
      byte len = (byte) rawData.length; 
      frame[2] = (byte) ((len >> 56) & (byte) 255); 
      frame[3] = (byte) ((len >> 48) & (byte) 255); 
      frame[4] = (byte) ((len >> 40) & (byte) 255); 
      frame[5] = (byte) ((len >> 32) & (byte) 255); 
      frame[6] = (byte) ((len >> 24) & (byte) 255); 
      frame[7] = (byte) ((len >> 16) & (byte) 255); 
      frame[8] = (byte) ((len >> 8) & (byte) 255); 
      frame[9] = (byte) (len & (byte) 255); 
      frameCount = 10; 
     } 

     int bLength = frameCount + rawData.length; 

     byte[] reply = new byte[bLength]; 

     int bLim = 0; 
     for (int i = 0; i < frameCount; i++) { 
      reply[bLim] = frame[i]; 
      bLim++; 
     } 
     for (int i = 0; i < rawData.length; i++) { 
      reply[bLim] = rawData[i]; 
      bLim++; 
     } 
     for (OutputStream writer : writers) { 
      writer.write(reply); 
      writer.flush(); 
     }    

    } 

도움을 주신 커뮤니티.

답변

2

몇 노트. 당신은 잘못

  • 당신은 제대로 바이트로 문자열을 변환하지 않는 길이를 처리하는

    다음은 간단한 예제 (UTF-8을 통해 수행해야합니다).

    아래 코드에 따라 사용이 허가됩니다 :

    package websocket; 
    
    import java.nio.ByteBuffer; 
    import java.nio.charset.Charset; 
    
    public class RawGenerate 
    { 
        /** 
        * The overhead (maximum) for a framing header. Assuming a maximum sized payload with masking key. 
        */ 
        public static final int OVERHEAD = 28; 
    
        public ByteBuffer asClientInitiatedTextFrame(String msg) 
        { 
         ByteBuffer buf = ByteBuffer.allocate(msg.length() + OVERHEAD); 
         putOpFin(buf,(byte)0x01,true); 
         byte mask[] = new byte[] { 1, 2, 3, 4 }; // Needs to be random 
         byte payload[] = msg.getBytes(Charset.forName("UTF-8")); // must be UTF-8 (per spec) 
         putLengthAndMask(buf,payload.length,mask); 
         for (int i = 0; i < payload.length; i++) 
         { 
          buf.put((byte)(payload[i] ^= mask[i % 4])); 
         } 
         buf.flip(); 
         return buf; 
        } 
    
        public static void putOpFin(ByteBuffer buf, byte opcode, boolean fin) 
        { 
         byte b = 0x00; 
         if (fin) 
         { 
          b |= 0x80; 
         } 
         b |= opcode & 0x0F; 
         buf.put(b); 
        } 
    
        public static void putLengthAndMask(ByteBuffer buf, int length, byte mask[]) 
        { 
         if (mask != null) 
         { 
          assert (mask.length == 4); 
          putLength(buf,length,(mask != null)); 
          buf.put(mask); 
         } 
         else 
         { 
          putLength(buf,length,false); 
         } 
        } 
    
        public static void putLength(ByteBuffer buf, int length, boolean masked) 
        { 
         if (length < 0) 
         { 
          throw new IllegalArgumentException("Length cannot be negative"); 
         } 
         byte b = (masked?(byte)0x80:0x00); 
    
         if (length > 0xFF_FF) 
         { 
          buf.put((byte)(b | 0x7F)); 
          buf.put((byte)0x00); 
          buf.put((byte)0x00); 
          buf.put((byte)0x00); 
          buf.put((byte)0x00); 
          buf.put((byte)((length >> 24) & 0xFF)); 
          buf.put((byte)((length >> 16) & 0xFF)); 
          buf.put((byte)((length >> 8) & 0xFF)); 
          buf.put((byte)(length & 0xFF)); 
         } 
         else if (length >= 0x7E) 
         { 
          buf.put((byte)(b | 0x7E)); 
          buf.put((byte)(length >> 8)); 
          buf.put((byte)(length & 0xFF)); 
         } 
         else 
         { 
          buf.put((byte)(b | length)); 
         } 
        } 
    } 
    
  • +0

    Eclipse Public License 1.0 당신의 응답을 주셔서 감사합니다 나는 그렇게 확인하지 자바 속기 명령이나 비트 사업자와 충분히 잘 알고 있지만 reputationmakes을지지 않습니다 현재 멀리있어 이 수업은 제 대신에 잘될 거라고 확신합니다. 다른 문자열을 처리하는 방법 내 코드가 어떻게 길이에 맞게 적절하게 조정될 수 있습니까? – JavaIntermediate

    +0

    여기에 별다른 약어가 없습니다. & (AND),'|'(OR),'^'(XOR),'>>'(SHIFT RIGHT)와 같이 비트 조작과 함께 바이너리/헥스를 배울 필요가 있습니다. . 길이 코드와 광산을 보면, 8 바이트 길이 버전의 경우 모든 8 바이트를 하나의'byte len '으로 채우려 고합니다. 작동하지 않을 것이다. 나는 이미 4 바이트 (32 비트)의 길이에 대해서만 걱정하고 있는데, 이는 이미 자바 int의 한계이기 때문이다. (길이가 2,147,483,647 바이트를 넘는 버퍼 포인트를 지원하지 않는 점) –

    +0

    그래서 나는 대신 내 코드를 사용했지만 실제로는 즉시 오류가 발생합니다. Google 오류 : 'ws : // localhost : 9999 /'에 대한 WebSocket 연결 실패 : 서버가 클라이언트에 보내는 프레임을 마스킹하지 않아야합니다. 내가 수업을 완전히 읽을 수 없기 때문에 나는 사과하여 이것을 고쳐 주겠습니까? 나는 내가 편집하거나 새로운 코멘트 덕분에 다시 해결책을 찾으면 계속 노력하고 해결해 나갈 것입니다! asClientInitiatedTextFrame 행을 putLengthAndMask (buf, payload)로 변경했습니다.길이, 마스크); ~에 putLength (buf, payload.length, false); 횡설수설을했고 다시 닫았다 – JavaIntermediate

    관련 문제