我从头开始在java中开发了一个websocket服务器。 javascript客户端在浏览器中运行:
function connectToServer() {
connection = new WebSocket("ws://" + document.domain + ":8351");
connection.onopen = function () {
};
connection.onmessage = function (e) {
handleServerResponse(e.data);
};
}
一切都很好,直到消息(json)达到65535字节。然后套接字关闭(我还没想到,如果客户端或服务器关闭了连接。
在浏览器控制台(试过几个浏览器)中,我看到: 在页面加载时,与ws:// localhost:8351 /的连接被中断。
在服务器端,我看到:java.net.SocketException:连接重置 在java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)
所以,如果问题出在握手中,或者我在服务器中错误地构建了框架,并且客户端关闭了连接,或者我正在编写流不正确的字节,而java io会关闭套接字。
我的代码(服务器):
1)握手(服务器响应)
String _01 = "HTTP/1.1 101 Switching Protocols\r\n";
String _02 = "Upgrade: websocket\r\n";
String _03 = "Connection: Upgrade\r\n";
String _04 = "Sec-WebSocket-Accept: " + responseKey + "\r\n";
String _05 = "Content-Encoding: identity\r\n";
2)构建框架(大型邮件应该分解为不同的框架吗?)
public static byte[] buildFrame(String message)
{
int length = message.length();
int rawDataIndex = -1;
if (length <= 125)
rawDataIndex = 2;
else if (length >= 126 && length <= 65535)
rawDataIndex = 4;
else
rawDataIndex = 10;
byte[] frame = new byte[length + rawDataIndex];
frame[0] = (byte)129;
if (rawDataIndex == 2)
frame[1] = (byte)length;
else if (rawDataIndex == 4)
{
frame[1] = (byte)126;
frame[2] = (byte)(( length >> 8 ) & (byte)255);
frame[3] = (byte)(( length ) & (byte)255);
}
else
{
frame[1] = (byte)127;
frame[2] = (byte)(( length >> 56 ) & (byte)255);
frame[3] = (byte)(( length >> 48 ) & (byte)255);
frame[4] = (byte)(( length >> 40 ) & (byte)255);
frame[5] = (byte)(( length >> 32 ) & (byte)255);
frame[6] = (byte)(( length >> 24 ) & (byte)255);
frame[7] = (byte)(( length >> 16 ) & (byte)255);
frame[8] = (byte)(( length >> 8 ) & (byte)255);
frame[9] = (byte)(( length ) & (byte)255);
}
for (int i = 0; i < length; i++)
frame[rawDataIndex + i] = (byte)message.charAt(i);
return frame;
}
3)将字节写入socket(我尝试过socket.setSendBufferSize和BufferedOutputStream,没有任何帮助)
socket.getOutputStream().write(byteMessage);
socket.getOutputStream().flush();
有没有人遇到同样的问题?欢迎任何帮助!
答案 0 :(得分:4)
我知道回答有点迟......但无论如何,我遇到了同样的问题和这段代码:
frame[1] = (byte)127;
frame[2] = (byte)(( length >> 56 ) & (byte)255);
frame[3] = (byte)(( length >> 48 ) & (byte)255);
frame[4] = (byte)(( length >> 40 ) & (byte)255);
frame[5] = (byte)(( length >> 32 ) & (byte)255);
frame[6] = (byte)(( length >> 24 ) & (byte)255);
frame[7] = (byte)(( length >> 16 ) & (byte)255);
frame[8] = (byte)(( length >> 8 ) & (byte)255);
frame[9] = (byte)(( length ) & (byte)255);
的工作原理。你的问题是你的变量“length”是一个32位的int。并且您正在执行8个字节的位移,因此您可以从内存中获取随机数据。如果将变量“length”定义为64位长,则可以正常工作。
long length = (long)message.length();
对我来说很完美。
我希望它可以帮助想要理解的人。
答案 1 :(得分:2)
我怀疑,位移代码populated over the internet不起作用。
找到以下代码(source):
frame[1] = (byte)127;
int left = length;
int unit = 256;
for (int i = 9; i > 1; i--)
{
frame[i] = (byte)(left % unit);
left = left / unit;
if (left == 0)
break;
}
它有效! 虽然我无法弄清楚,但有什么区别。