Giter Site home page Giter Site logo

knowno / fuck_tcp Goto Github PK

View Code? Open in Web Editor NEW

This project forked from across-travel/fuck_tcp

0.0 1.0 1.0 49 KB

炮打TCP - 关于一而再再而三的粘包拆包问题的大字报

Home Page: http://www.ideawu.net/blog/archives/1027.html

Makefile 1.11% C 98.89%

fuck_tcp's Introduction

FUCK TCP

测试工具说明

测试工具首先定义了一种简单的报文格式:

Packet := header + body
header := length + '|'
length := [0-9]+
body   := text

Example:

1|A
12|Hello World!

该报文格式用至少一个 digit 充当报文的头部,这些 digit 组成的数字表示后面跟着的报体的长度。

文件 功能
server.c 用于模拟粘包和拆包的服务器
client.c 一个可以适应粘包和拆包的客户端

用法:

make
./server 7001
# or
./server 7001 debug

启动了一个监听 7001 端口的 TCP 服务器,你可以用自己写的客户端连接上去,接收消息。如果收到的消息是:

test
Hello
World!
abcdefghij0123456789

那么说明你写的代码可以正常工作。请把你的client代码以issue形式发出来,不限语言,PHP,Python, 闹得js,Java 等等都可以。

炮打TCP - 关于一而再再而三的粘包拆包问题的大字报

TCP 所谓的粘包和拆包问题,是技术圈里最奇葩的问题之一!

一而再,再而三,就跟**的**球迷支持**足球队一样,前赴后继。有时候同一个人多次在犯同一个错误,有时候是前脚一个犯错了后脚又来一个还犯同样的错。即使是最优秀的程序员,也会在这个问题上面栽跟头,思维甚至很难转过弯,很久才能意识到自己的错误。而低水平的程序员就更不用说了,很多人到死都没有理解这个错误并解决掉,只是逃掉了而已。

我们固然可以认为原因是某些人学艺不精,但那么多的人,其中包括无数的优秀程序员在 TCP 粘包和拆包问题在犯错误,难道我们不能说,这其实是 TCP 自身的原因吗?

在我看来,这个问题的出现,原因就在于 TCP 协议是有原罪的 -- 也就是 TCP 协议所谓的“流式”协议。所以,我要炮轰 TCP!

经过几十年的验证,除了几数几个网络协议会用到 TCP 所谓的流式特性之外,没有任何应用协议使用流式特性。我们必须承认,所有的应用层协议都是基于报文的协议,而不是流式协议。而某些名字中带有”流(Stream)"字样的协议,如 RTP,流媒体等,其本质是无数小体积的报文按顺序拼接而成,根本就和 TCP 的流式没有任何关系!

那么我们就可以确定,数据的本质是报文,流数据是某类报文数据的一种伪称。事实,TCP 的流就是基于 IP 报文的。

因为“流”是一个伪抽象的概念,所以流式协议是违反人的天性的和事物的内在逻辑的。万物的本质是报文。这因为如此,”流”所引出的粘包拆包问题,就必然会一而再,再而三,大量地出现。

炮轰之后,我们要怎么解决问题呢?

由于 TCP 协议已经成为事实上的基础,所以淘汰掉 TCP 是不可想象的。我们要做的是,找到正确的编程代码,解决粘包拆包问题。经过无数人的探索,以及无数人一次又一次重复的愚蠢错误的反证,我发现了解决 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 中读取流式数据,每一次读取到的数据的长度是不可预期,也就是,读取到的数据长短不一,无法保证,这就是所谓“流式”引出的问题。

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

你只需要死记硬背上面的正确代码即可。不死记硬背也一样,最终你还是要得出和我相同的结论写出和我一样的代码。那么,何不现在就死记硬背呢?

最后,附上经典的错误代码:

tcp.read(tmp, HEADER_LEN);
header = parse_header(tmp);
tcp.read(tmp, header.body_len);
body = parse(tmp);

这样的代码当然是错误的,这么简单代码怎么可能是对的?如果对了,TCP 还是 TCP 吗?

如果你认为本文有用,请关注这个 GitHub 项目:https://github.com/ideawu/FUCK_TCP 让更多人一起炮打 TCP!

原文:http://www.ideawu.net/blog/archives/1027.html

fuck_tcp's People

Contributors

ideawu avatar

Watchers

 avatar

Forkers

bharatpotnuri

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.