Socket组包和分包快速理解及相关示例

本文详细介绍了在Socket通信中如何进行数据的分包和组包操作,包括使用字节流进行组包和拆包的过程,以及C++和Java语言的具体实现案例,帮助读者理解并掌握Socket通信中的关键环节。

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

socket 分包和组包:建议使用字节流。组包和拆包是一个近似序列化和反序列化的过程。

目录

组包

拆包

C++组包发送与拼包解析

组包拆包示例


消息形式为: 包长度(short)+包头(short)+messages(string)+包尾(short)

组包

组包的意思是按照协议构建二进制数组数据。

private void writesMessage(short cmd , String messages, short move,Socket socket) { 
        initOutput(); 
        try { 
            output.writeShort(cmd); 
            output.writeChars(messages); 
            output.writeShort(move); 
            MyUtil.sendMessage(socket, byteOutput.toByteArray()); 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
    } 
     
    private void initOutput() 
    { 
        byteOutput = new ByteArrayOutputStream(); 
        output = new DataOutputStream(byteOutput); 
    } 
 
/**
     * 发送数据到网络流
     * 
     * @param socket
     * @param bytes
     * @throws Exception
     */ 
    public static void sendMessage(Socket socket, byte[] bytes)throws Exception { 
        DataOutputStream dataOutput = new DataOutputStream(socket.getOutputStream()); 
        // 编写数据的长度 
        dataOutput.writeShort(bytes.length); 
        dataOutput.write(bytes); 
        dataOutput.flush(); 
    } 


拆包

按照协议将二进制数组数据解析为对应的字段。

 short len = br.readShort();//br 为DataInputStream 
 short cmd = br.readShort(); 
 byte[] bytes = new byte[len]; 
 br.read(bytes, 0, len-4); 
 String messgeString = new String(bytes);  
 System.out.println("首条消息:"+messgeString); 
 short move = br.readShort(); 

C++组包发送与拼包解析

BYTE m_Buffer[100000];
int m_iLen=0;
void RecvTCP(const char * pBuffer, int iLen)
{
    memcpy(m_Buffer + m_iLen, pBuffer, iLen);
    int length = iLen + m_iLen;
    int nPackage = length / 1008;
    for (int i = 0; i < nPackage;i++)
    {
       //处理…
    }
    m_iLen = length - 1008 * nPackage;
    memcpy(m_Buffer, m_Buffer + nPackage * 1008, m_iLen);
}

组包拆包示例

XTCP 一个便捷的TCP消息包拼装和解析框架

【Java TCP/IP Socket】构建和解析自定义协议消息(含代码)

定长消息报文的组包与解包简单封装(Java实现)

自定义Udp/Tcp协议,通信协议Socket/WebSocket,IM粘包、分包解决等(2),ProtocolBuffer

Java网络编程(五)socket的半包,粘包与分包的问题

以下是一个简单的示例代码,展示了如何使用 socket 分包传输 mat: 发送方代码: ```python import socket import numpy as np import cv2 # 将 mat 转换为字节数 def mat_to_bytes(mat): return mat.tobytes() # 创建 socket 对象 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 连接服务器 server_address = ('localhost', 8888) client_socket.connect(server_address) # 加载图像 img = cv2.imread('test.jpg') # 将图像转换为 mat 对象 mat = np.array(img) # 将 mat 转换为字节数 data = mat_to_bytes(mat) # 发送头 header = len(data).to_bytes(4, byteorder='big') client_socket.sendall(header) # 分包发送数据 buffer_size = 1024 offset = 0 while offset < len(data): size = min(buffer_size, len(data) - offset) client_socket.sendall(data[offset:offset+size]) offset += size # 关闭连接 client_socket.close() ``` 接收方代码: ```python import socket import numpy as np import cv2 # 将字节数转换为 mat def bytes_to_mat(data): mat = np.frombuffer(data, dtype=np.uint8) mat = np.reshape(mat, (-1, 3)) mat = np.reshape(mat, (height, width, 3)) return mat # 创建 socket 对象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定地址和端口号 server_address = ('localhost', 8888) server_socket.bind(server_address) # 开始监听 server_socket.listen(1) # 等待客户端连接 client_socket, client_address = server_socket.accept() # 接收头 header = client_socket.recv(4) data_size = int.from_bytes(header, byteorder='big') # 接收数据 buffer_size = 1024 data = b'' while len(data) < data_size: recv_size = min(buffer_size, data_size - len(data)) recv_data = client_socket.recv(recv_size) data += recv_data # 将字节数转换为 mat 对象 img = bytes_to_mat(data) # 显示图像 cv2.imshow('image', img) cv2.waitKey(0) # 关闭连接 client_socket.close() server_socket.close() ``` 请注意,这只是一个简单的示例代码,实际应用中还需要考虑数据的完整性和正确性,以及网络传输的稳定性等因素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值