« | September 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | | | | | |
| 登录 |
| 联系我 email: binaryluo(at)gmail.com
Blog信息 |
blog名称:二进制-虚心使人进步,骄傲使人落后。 日志总数:42 评论数量:370 留言数量:88 访问次数:639272 建立时间:2005年2月19日 |

| |
[网络编程技术]TCP数据段的组装 原创空间, 心得体会, 软件技术, 电脑与网络
binaryluo 发表于 2006/4/19 11:07:49 |
重装TCP数据段,我看了《TCP/IP详解卷二:实现》觉得它里面的实现考虑的很全面,当然也就很复杂。而我组装只是为了监视,所以不必那么复杂,于是自己想了一个方法。现在我已经根据这个方法成功组装TCP分段,所以这个方法是可行的。 另外,我的IP分片的组装用的方法跟这个方法也差不多。 首先说下存储tcp分段的数据结构:一个二维链表,我把它叫作重装表。具有相同socket对(源ip地址、目的ip地址、源端口号、目的端口号)的tcp数据包放在一个横向的链表里,该链表的头节点只保存了源ip地址、目的ip地址、源端口号、目的端口号这些信息。如下图所示:
500)this.width=500'>
然后介绍重装TCP数据段的方法:1.每到来一个tcp数据包(pkt),我先将该数据包的源ip地址、目的ip地址、源端口号、目的端口号取出来在重装表(tpq_tbl)中纵向的链表中查找有没有与它相匹配的链表(fp)存在,如果有,就把pkt数据包放入与它有相同socket对的fp链中,放入链表的时,我先查找pkt的顺序号在链表中的适当位置,然后才放入;如果没有,则在tpq_tbl中新创建一个该类型的链表头节点,然后再将其放入新创建的链表中。2.每当在fp中放入一个tcp数据段后,我就检查fp链表中的数据段是否已经到齐了(判断方法下面介绍),若到齐,就将个链表中所有数据段的数据部分拼接到一起,得到应用层报文,然后释放该链表,然后重复1-2步骤;若没到齐,直接重复1-2步骤。 关于判断一个链表中tcp数据段是否到齐的方法: 使用的变量说明: count计数器,表示当前链表中的所有tcp数据段数据部分的长度之和。每当在该链表中加入一个新tcp数据段时,我都会将count累加上该tcp数据段的数据部分的长度。 syn_seq,表示本次tcp连接的第一个数据包的顺序号,也就是建立tcp连接时的第一次握手的SYN包的顺序号。 fin_seq,表示本次tcp连接的最后一个数据包的顺序号,也就是关闭tcp连接时的第二个FIN包的顺序号。 判断:当(fin_seq - syn_seq)与count相等时,就说明tcp数据段已经到齐,否则就是没有到齐。
|
回复:TCP数据段的组装 原创空间, 心得体会, 软件技术, 电脑与网络
北欧神话(游客)发表评论于2009/3/18 11:17:12 |
我最近在做邮件审计方面的东东,你的博客写的很好,谢谢~
|
回复:TCP数据段的组装 原创空间, 心得体会, 软件技术, 电脑与网络
smallbear(游客)发表评论于2009/2/3 15:30:03 |
楼主请转发一份
xiaoguibibi@163.com
|
回复:TCP数据段的组装 原创空间, 心得体会, 软件技术, 电脑与网络
ykk(游客)发表评论于2009/2/1 15:52:01 |
楼主请转发一份
ykk99114@sohu.com
|
回复:TCP数据段的组装 原创空间, 心得体会, 软件技术, 电脑与网络
ffsolp(游客)发表评论于2008/6/3 1:30:28 |
最近正在做TCP包的重组,不知道博主是否能提供下源码,不胜感激!我的邮箱:cxcclv@126.com
|
回复:TCP数据段的组装 原创空间, 心得体会, 软件技术, 电脑与网络
eagle0033(游客)发表评论于2008/5/12 21:08:58 |
在重组时是不是 要分别重组 客户端发往服务器端的 和服务器端发往客户端的数据以下为blog主人的回复: 本机的协议栈只处理本机接收到的数据包,即只重组其他主机发送到本机的数据包;本机发送给其他主机的数据包将由其他主机的协议栈处理。
|
回复:TCP数据段的组装 原创空间, 心得体会, 软件技术, 电脑与网络
eagle0033(游客)发表评论于2008/5/8 16:26:23 |
另外我也有这些问题 我的邮箱 eagle0033@163.com
问题1:
在描述判断某链表中的TCP包是否已经接收完整,您是
通过统计所有相关包的数据长度和(count),再将它同数据
包的 syn_seq与fin_seq的差比较,如果count=syn_seq-fin_seq
就表示tcp数据包都到齐了。
这里我不明白,syn_seq是tcp连接第一数据包的顺序号,
fin_seq是最后一个包的顺序号,它们的减,就总是表示整个tcp
的数据长度吗?同时,你又是以哪个、怎么判断数据包的顺序的呢?
问题2:
如果应用是在通过TCP在传输一个比较大的文件,比如2G,
您又是怎么处理这样的大文件数据包的接收的呢?全部一次性
在内存中重组完,感觉有点不现实一样!
以下为blog主人的回复: binaryluo 发送至 Yang 显示详细信息 07-1-8 回复你好!A1:你的理解有点错误。首先,一个TCP数据段的顺序号是数据段的第一个字节流中的编号。例如:一个由500 000字节组成的文件、1000字节的MSS(Maximum Segement Size),分成500个数据段,第一个数据段的顺序号被分配0,第二个的被分配1000,地三个的被分配2000等等。因此,(fin_seq - syn_seq)等于count。其次,count表示的是"不包含最后一个数据段(fin数据段)的长度的其余数据段的总长度"。
A2:这个问题不是TCP/IP协议栈的考虑范围。因为在TCP/IP协议栈中没有考虑应用层报文的大小,只是对传输层、网络层、链路层的PDU的大小进行了限制。如果遇到很大的报文(比如你说的2G),协议栈仍然只维护它自己的数据结构(双向链表),对于内存是否存储得下这么大的空间那个属于虚拟内存的问题,由操作系统管理。当然你在实现的时候可以考虑这些问题并作一定的优化,尽量使协议栈的效率高。--binary
2007.1.8
|
|