我正在尝试重新发明轮子并创建我自己的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();
}
}
感谢社区提供任何帮助。
答案 0 :(得分:2)
一些注释。
这是一个简单的例子。
以下代码的许可位于: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));
}
}
}