[心缘地方]同学录
首页 | 功能说明 | 站长通知 | 最近更新 | 编码查看转换 | 代码下载 | 常见问题及讨论 | 《深入解析ASP核心技术》 | 王小鸭自动发工资条VBA版
登录系统:用户名: 密码: 如果要讨论问题,请先注册。

[备忘]TCP 粘包和拆包的大概方法

上一篇:[备忘]postgresql使用setFetchSize的注意事项
下一篇:[转帖]Nginx反向代理至非80端口时丢失端口

添加日期:2021/2/23 13:35:41 快速返回   返回列表 阅读993次
https://github.com/ckliufuchao/fuck_tcp

解决 TCP 粘包和拆包问题的代码架构如下:


char tmp[];
Buffer buffer;
// 网络循环:必须在一个循环中读取网络,因为网络数据是源源不断的。
while(1){
    // 从TCP流中读取不定长度的一段流数据,不能保证读到的数据是你期望的长度
    tcp.read(tmp);
    // 将这段流数据和之前收到的流数据拼接到一起
    buffer.append(tmp);
    // 解析循环:必须在一个循环中解析报文,应对所谓的粘包
    while(1){
        // 尝试解析报文
        msg = parse(buffer);
        if(!msg){
            // 报文还没有准备好,糟糕,我们遇到拆包了!跳出解析循环,继续读网络。
            break;
        }
        // 将解析过的报文对应的流数据清除
        buffer.remove(msg.length);
        // 业务处理
        process(msg);
    }
}


这段代码是终极地解决 TCP 粘包和拆包问题的代码!

这段代码之所以正确,是因为它包含了两个循环:网络循环和解析循环。

网络循环用于从 TCP socket 中读取流式数据,每一次读取到的数据的长度是不可预期,也就是,读取到的数据长短不一,无法保证,这就是所谓“流式”引出的问题。

而解析循环的功能是从拼接后流数据中,尝试解析出多个报文。注意,是多个报文,不是一个。因为所谓的粘包问题存在,所以可能是多个,而不是一个。如果解析不成功,那说明是遇到了拆包问题,我们继续读网络数据。
 

评论 COMMENTS
没有评论 No Comments.

添加评论 Add new comment.
昵称 Name:
评论内容 Comment:
验证码(不区分大小写)
Validation Code:
(not case sensitive)
看不清?点这里换一张!(Change it here!)
 
评论由管理员查看后才能显示。the comment will be showed after it is checked by admin.
CopyRight © 心缘地方 2005-2999. All Rights Reserved