Java Websocket文本框架长度错误> = 128?

时间:2013-08-21 21:44:34

标签: java websocket

我正在尝试重新发明轮子并创建我自己的websocket服务器。它可以在Google Chrome和Firefox上正常连接,并且可以正确接收和回显文本框,最长可达127个字符。但是,Google除外之外还给出了以下错误:

与'ws:// localhost:9999 /'的WebSocket连接失败:必须使用最小字节数来编码长度

Firefox会接收/解释前几个字符,有时会失败代码:1006。

服务器显示正在完整地接收消息并尝试完全广播它,没有运行时错误或。它也是我的System.out.println()所示的16位长度创建者。我的服务器java控制台读取:

websocket服务器启动了 客户连接 收到消息 1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij12345678 广播:1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij12345678 第二个数据

我正在编写一个帧测试器来测试我正在播放的帧,但我希望社区能够为我节省一些腿部工作。真正奇怪的是126和127个有效载荷长度工作,并使用2个字节的长度反映。

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

    }

感谢社区提供任何帮助。

1 个答案:

答案 0 :(得分:2)

一些注释。

  1. 您处理的长度不正确
  2. 您没有正确地将字符串转换为字节(必须通过UTF-8完成)
  3. 这是一个简单的例子。

    以下代码的许可位于:Eclipse Public License 1.0

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