Websocket:发送超过65535字节的消息失败 [英] Websocket: sending messages over 65535 bytes fails

查看:248
本文介绍了Websocket:发送超过65535字节的消息失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从头开始在java中开发了一个websocket服务器。 javascript客户端在浏览器中运行:

I've developed a websocket server in java from scratch. The javascript client is running in browser:

function connectToServer() {
    connection = new WebSocket("ws://" + document.domain + ":8351");       
    connection.onopen = function () {
    };

    connection.onmessage = function (e) {
        handleServerResponse(e.data);
    };
}

在消息(json)达到65535字节之前一切正常。然后套接字关闭(我还没弄明白,如果客户端或服务器关闭连接。

Everything is fine until the messages (json) reach 65535 bytes. Then the socket is closed (i have not figured out, if client or server closes the connection.

在浏览器控制台(试过几个浏览器)中我看到:
页面加载时,与ws:// localhost:8351 /的连接被中断。

In browser console (tried several browsers) I see: The connection to ws://localhost:8351/ was interrupted while the page was loading.

在服务器端,我看到:java.net.SocketException:Connection reset
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)

On server side, I see: java.net.SocketException: Connection reset at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)

所以,如果问题出在握手中,或者我在服务器中错误地构建了框架客户端关闭连接或我写的字节流不正确,java io关闭套接字。

So, if the problem is in handshake or I build the frame incorrectly in server and the client closes the connection or I'm writing the bytes to stream incorrect and the java io closes the socket.

我的代码(服务器):

1)握手(服务器响应)

1) Handshake (server response)

  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)构建框架(大型邮件应该分解为不同的框架吗?)

2) Building the frame (Should large messages be broken up to different frames?)

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.setSendBufferSize和BufferedOutputStream什么都没有帮助)

3) Writing bytes to socket (I've tried socket.setSendBufferSize and BufferedOutputStream, nothing helps)

socket.getOutputStream().write(byteMessage);
socket.getOutputStream().flush();

有没有人遇到同样的问题?欢迎任何帮助!

Has anyone encountered the same problem? Any help is welcome!

推荐答案

我知道回答有点迟......但无论如何,我遇到了同样的问题,此代码:

I know it's a bit late for answering... but anyway, i faced the same problem and this code:

    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位长则可以正常工作。

works. Your problem here is that your variable "length" is an int that is 32bits. And you are performing bit shifting on 8 bytes so you get random data from the memory. If you define your variable "length" as a 64 bits long then it works.

long length = (long)message.length();

对我来说非常合适。

I希望它可以帮助想要理解的人。

I hope it can help someone who wants to understand.

这篇关于Websocket:发送超过65535字节的消息失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆