websocket传输数据大小限制_WebSocket传输超过126字节数据的方法

当使用Java的Socket实现WebSocket服务端并传输数据时,遇到超过126字节的数据会导致连接断开。为解决此问题,文章详细介绍了三种处理方法:1. 对于小于126字节的数据,直接发送;2. 对于125到65535字节的数据,数据头第二个字节设为126,后续两个字节存储长度;3. 对于大于65535字节的数据,数据头第二个字节设为127,接下来8个字节存储长度。通过这种方式,可以成功传输大一些的数据而不再需要分批传递。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前用Java的Socket模拟HTTP传输实现了WebSocket的服务端,并成功与客户端握手

但是有个问题,就是从Server传输数据超过126字节就不行,连接自动断开还报错InputStream in=socket.getInputStream();

OutputStream out=socket.getOutputStream();

byte[] buff=new byte[3072];

int hasRead=0;

while((hasRead=in.read(buff)>0){

byte[] pushHead=new byte[2];    //在传递数据前要传递这个数据头

String x="要传输的数据......";

pushHead[0]=buff[0];            //数据头数组的第一个字节是接收到的数据的第一个字节

//第二个字节是要传输数据的字节数组长度转化成的字节

pushHead[1]=(byte)x.getBytes("UTF-8").length;

out.write(pushHead);            //先传递数据头

out.write(x.getBytes("UTF-8");  //再传递数据

}

上面的代码在传递的数据转化成的字节数组长度小于126时是OK的,但是>=126时就报错。

因为字节的范围是-128~127,所以传输数据长度大于125就报错

那就要另外的处理方法

传输跟据数据长度分三种情况,即有三种范围小于126,那么上面的代码就OK了

大于125 小于65536  那么数据头的第二个字节存的是(byte)126,第三第四个字节存的是数据长度

大于65535   数据头第二个字节存的是(byte)127,后面再有8个字节存数据长度

这样说过于平面,看代码吧(代码也是平面的好不 (╯°Д°)╯( ┻━┻    )

InputStream in=socket.getInputStream();

OutputStream out=socket.getOutputStream();

byte[] buff=new byte[3072];

int hasRead=0;

while((hasRead=in.read(buff)>0){

byte[] pushHead;    //在传递数据前要传递这个数据头

String x="要传输的数据......";

int length=x.getBytes("UTF-8").length;

if(length<126){

pushHead=new Byte[2];

pushHead[0]=buff[0];    //数据头数组的第一个字节是接收到的数据的第一个字节

//第二个字节是要传输数据的字节数组长度转化成的字节

pushHead[1]=(byte)x.getBytes("UTF-8").length;

out.write(pushHead);            //先传递数据头

}

else if(length>125 && length<65536){

pushHead=new Byte[4];

pushHead[0]=buff[0];

pushHead[1]=(byte)126;

pushHead[2]=(byte)((length>>8) & 0xFF);

pushHead[3]=(byte)(length & 0xFF);

out.write(pushHead);

}

else if(length>65535){

pushHead=new Byte[4];

pushHead[0]=buff[0];

pushHead[1]=(byte)127;

pushHead[2]=(byte)((length>>56) & 0xFF);

pushHead[3]=(byte)((length>>48) & 0xFF);

pushHead[4]=(byte)((length>>40) & 0xFF);

pushHead[5]=(byte)((length>>32) & 0xFF);

pushHead[6]=(byte)((length>>24) & 0xFF);

pushHead[7]=(byte)((length>>16) & 0xFF);

pushHead[8]=(byte)((length>>8) & 0xFF);

pushHead[9]=(byte)(length & 0xFF);

out.write(pushHead);

}

out.write(x.getBytes("UTF-8");  //再传递数据

}

这样大一些的数据也能一次传了,原先只能传不超过126字节数据时,要把数据分割分批传递,客户端接收后再组装或其它方式处理。不过目前只试了字符串的传输,还没试过图片,回头试试

### WebSocket 数据传输格式详解 #### 1. 握手过程 浏览器通过 `GET` 请求发起 WebSocket 连接,该请求包含特定的 HTTP 头部字段用于标识这是一个 WebSocket 协议升级请求。当服务器检测到请求头部含有 `"Upgrade: websocket"` 字段时,会识别这是 WebSocket 的连接尝试并作出响应完成握手。 一旦握手成功建立之后,客户端和服务端之间就可以基于 TCP 长链接双向通讯了[^2]。 #### 2. 数据帧结构 WebSocket 使用一种称为“帧”的单元来进行数据交换。每个消息可以由多个连续的数据帧组成。单个数据帧具有以下组成部分: - **FIN**: 表明当前帧是否为一条完整的消息的最后一部分。 - **RSV1, RSV2, RSV3**: 保留位,默认情况下应设置为0;这些位可用于将来扩展功能而不破坏现有实现兼容性。 - **Opcode (操作码)**: 定义了此帧的目的或类型,比如文本(`TEXT`)、二进制(`BINARY`)以及其他控制命令如关闭连接(`CLOSE`)等。 - **Mask(掩码标志)**: 如果值为1则表示后续的有效载荷数据已被混淆处理过,在发送给服务端之前需要解密才能读取真实内容。通常只有来自用户的输入才会被加密以保护隐私安全。 - **Payload length(有效负载长度)**: 显示跟随其后的实际应用层数据大小。对于较长的信息体可能还需要额外字节来精确描述整个尺寸。 - **Masking-key(掩码键)**: 当 Mask 设置为 true 时提供四个随机生成字节作为加/解密算法中的种子材料。 - **Application data(应用程序数据)**: 实际要传递的内容本身,可能是 UTF-8 编码字符串或者是原始八比特序列形式的任意二进制资料. 以下是 Python 中创建一个简单的 WebSocket 帧的例子: ```python import struct def create_frame(data, opcode=0x1): # 默认opcode为1代表text frame fin = 0b1 # 最终片段标记置1 rsvs = 0b0 * 3 # 清除预留位 payload_length = len(data) if isinstance(data, str): encoded_data = data.encode('utf-8') elif isinstance(data, bytes): encoded_data = data else: raise ValueError("Unsupported data type") header = bytearray() b1 = fin << 7 | opcode & 0xf header.append(b1) if payload_length <= 125: header.append(payload_length) elif payload_length >= 126 and payload_length <= 65535: header.extend(struct.pack("!BH", 126, payload_length)) else: header.extend(struct.pack("!BQ", 127, payload_length)) return header + encoded_data ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值