文档章节

重读TCP/IP(5)之TCP头部

terry_hding
 terry_hding
发布于 2016/05/21 00:04
字数 2639
阅读 733
收藏 16

TCP概述

前一篇讲述了IP,它是一个不可靠的,无连接的,无序的,无流控的,只顾寻找最佳路由进行转发,提供最好的传输,既然IP不管这些,是因为这些都由TCP来完成,IP层只需要传送,不管到达,复杂度在于路由选择,TCP接管了有序,有连接的,可靠的服务,复杂度也就在于如何有序,如何控制流量,使得传输可靠,两个协议侧重面不同,但却又相辅相承,TCP保证正确的传输,IP保证最佳路径传输,IP不保证到达,TCP保证到达。想要知道TCPIP不一样的地方就需要了解它的头部和IP有什么区别。

TCP头部

Source port 源端口和Destination port 目的端口16位,告知主机该报文段是来自哪个源端口以及传给哪个上层协议(应用层)目的端口的,进行TCP通信,客户端通常使用系统自动选择的临时端口号,而服务器则使用一些知名服务的端口号。

应用程序的端口号和应用程序所在主机的IP地址统称为socket(套接字),IP:XX, 在互联网上socket唯一标识每一个应用程序,源端口+源IP+目的端口+目的IP称为套接字对,一对套接字就是一个连接,一个客户端与服务器之间的连接。

Sequence Number 序列号:32位,一次TCP通信(建立到断开)过程中某一个传输方向上的字节流的每个字节的编号,它保证了TCP通信的有序性,解决网络包乱序的问题,由于有了这个编号,接收端可以根据这个序号进行确认,可以保证每个分段在原始数据包中的位置,初始序列号由自己定,而后绪的序列号由对端的ACK决定:SN_x = ACK_y (x的序列号=y发给xACK)

Acknowledgement Number确认号:32位,用来另一方发送来的TCP报文段的确认响应,其值是收到的TCP报文段的序号+1,也是对端下一次发报文段过来的序号,期望对端以这个序号开始发送自己的分组,这样可以保证发送过来的报文是有序的,否则发送端不能确认之前的报文是否有被收到,而要决定是否重传, ACK_y = SN_x+TCP_len+Flag(ACK的值是由对方的tcp_len+对方的seq值以及flag的值来决定,syn,fin都消耗一个序号,而ack无需任何代价,因为确认序号与ACK标志是在一起的,属于TCP头部一部分,不消耗序号)

Head Length 报头长度:4位,标识该TCP头部有多少个32bit字节,这个跟IP报文中的HL一样,都是计算头部长度,最小IPTCP头部都是20字节,值为5,即4*5=20TCP最大头部为60字节, 16*4,一般情况下TCP头部为32字节,20字节头+12字节的options,这个字段有时又叫offset,数据偏移,它确定了TCP数据在一个分组中从何开始

Flag标志位:

·       URG标志: urgent pointer是否有效,1表示该分段包含紧急数据

·         ACK  标志:表示确认号是否有效,携带ACK标志的TCP报文段为确认报文段

·         PSH标志:发送方使用该标志通知接收方将所收到的数据全部提交给接收进程,这里的数据包括PUSH过去的,以及接收方已经接收的那些没有PUSH标志的其它数据,目的是让接收端立即提交进程处理而不要判断是否还会有额外的数据到达。提示接收应用程序立即从TCP接收缓冲器中读走数据,通常对时效性比较高的服务,如telnet。也常见TCP分片中,一个报文段发不完,此时需要清空缓存,以备后面的大数据到来

·         RST 标志:表示要求对方重新建立连接,通常发生在对端端口没打开,对端会发给一个带R标志的复位报文段,TCP提供了一个异常终止的方法,就是发TCP报文段,还有一种情况就是连接属于半打开状态,此时写数据,会收到RST,因为连接并不真实存在

·         SYN 标志:请求建立一个连接,主要是协商ISN,初始序列号,完成三次握手

·         FIN 标志:表示通知对方,本端数据已传完,要关闭连接,完成四次握手,成功关闭,与RST不同的是,这是正常的关闭,而不是异常

Window Size窗口大小:16位,它是TCP流量控制的一个手段,这里说的窗口是接收通告窗口,即告诉对方本端TCP接收缓冲区还能容纳多少字节的数据,这样对方就需要控制发送数据的速度

Checksum 校验和:TCP的校验和由发送端填充,由接收端执行CRC算法是否得到全1,以检验TCP报文段在传输过程中是否损坏,它与IP的校验和不同,IP是头校验,而TCP的校验和不仅是TCP头部,还有TCP的数据,以及IP源地址,目的地址,协议(0x06,TCPsegment Length)计算而来,每两个字节为一单位进行反码求和,其中协议为低字节,TCP报文长度也为单低字节进行反码求和,高位溢出加到低位

#/usr/bin/env python

def checksum(*aList):
    sum = 0x0
    for i in range(len(aList[0])):                         #aList[0]=alist
        if i%2 == 0:
            aList[0][i]=aList[0][i]<<8                     #奇数位左移8位,成为高8位字节
    for i in aList[0]:
        sum = sum+i                                        #求和
        sum=(sum>>16)+(sum&0xffff)                         #循环相加,溢出就加到低位
        result = 2**16-1-sum                               #算反码=2**模-原码
        result = hex(result)                               #十六进制转换
    return result

 

alist = [0xc0,0xa8,0x02,0x65,                              #192.168.2.101 源IP

         0xc0,0xa8,0x02,0x6f,                              #192.168.2.111 目的IP

         0x11,0xbf,0x1f,0x40,0x12,                         #从0x11开始到0x02都是TCP

         0xad,0xd2,0xf9,0x00,0x00,0x00,0x00,

         0x80,0x02,0xff,0xff,0x00,0x00,0x00,               #0xff后面的0x00,0x00是因为发端算校验和先填校验码为0,随后算出来的值再到收端进行计算可得ffff

         0x00,0x02,0x04,0x05,0xac,0x01,0x03,

         0x03,0x02,0x01,0x01,0x04,0x02,                    

         0x00,0x20,0x00,0x06]                              #0x00,0x20 TCP报文长度(头和数据),由于现在没有数据,因此只有头+选项共32字节,0x20,作为低字节,因此前面加0x00
                                                           #0x00,0x06 TCP协议号,作为低字节,前面补0x00
print checksum(alist)

 ---------------------------------------------------------------------------

0xd253

Urgent Point 紧急指针:16位,是一个正的偏移量,它和序号字段的值相加表示最后一个紧急数据的下一字节的序号,因此确切的说是一个紧急偏移,TCP是字节流不存在优先级,但是可以设置紧急位表示该报文有紧急数据,通过紧急指针知道这个报文中紧急数据的最后一个字节,但是并不知道这个报文中紧急数据的具体位置,因为初始位置不能确定,有可能前面有普通数据。

options选项:TCP的选项是可变的,但是最多只包含40个字节,因为TCP头部最大60字节,固定部分20字节,选项的结构如下,所有的选项都遵循下面的格式

kind(1字节) length(1字节)                         info(n字节)           

选项的第一个字段为Kind类型,有的选项没有lengthinfo, 有的都有,但总共分为7种选项

Kind=0是选项表结束选项

Kind=1是空操作NOP,一般用于将TCP的头部填充为4字节的整数倍

Kind=2是最大报文段长度,TCP连接初始化时会协商MSS(max segment size),TCP模块通常设置为1460,因为以太网最大数据报为1500IP20 TCP20,最大段长就为1460,这也就避免了IP分片,也就是我们说的在TCP应用中一般看不到IP分片的原因

Kind=3窗口扩大因子,虽然窗口大小在连接时可以协商,但窗口远不止65535,当窗口大小为N,当移位数为M时,窗口大小在实际传输中是N*2**M

Kind=4是选择性确认(Selective Acknowledgement, SACKTCP重传机制指的是如果某个TCP报文丢失,TCP会重传最后确认的TCP报文段的后绪报文段,但之前正确传输的报文段也要重传,这就降低了性能,SACK可以使TCP只重传丢失的报文段,而不用把所有未确认的报文都重传,连接时会选择是否启用SACK技术

Kind=5SACK实际工作的选项,该选项的参数告诉发送方已经收到并缓存的不连续的数据块,从而让发送端可以据此检查并重发丢失的数据块,每个块边沿包含4个字节,每个块的左边沿表示不连续块的的第一个数据号,右边沿不连续块的最后一个数据的序号的下一个序号,这样一对参数之间的数据就是没有收到的块,一个块信息占用8字节,TCP头部最多只包含4个这样的不连续块,因为4*8+2<40

Kind=8是时间戳选项,该项提供较为准确的,通信双方之间的回路时间(RTT),为流量控制提供重要信息,并且也为SN的回绕提供信息,在一个带宽很高的环境中,充号最大为65535,很短的时间,序号就会耗尽从而从0开始,有了timestamp后,我们就可以避免同样的序号的包如何辨别先后的问题

参考:

http://www.kuqin.com/shuoit/20140611/340486.html TCP的那些事儿上
http://www.kuqin.com/shuoit/20140611/340485.html TCP的那些事儿下
TCP/IP guide
TCP/IP 协议卷1

 

© 著作权归作者所有

terry_hding
粉丝 40
博文 133
码字总数 139264
作品 0
杨浦
QA/测试工程师
私信 提问
重读TCP/IP协议(1)--网络概述

以前很多不同的厂家生产各自的计算机,有着不同的操作系统,只有同样的操作系统的计算机才能通信,但TCP/IP允许这些不同的操作系统的计算机互相进行通信,他们都准守则一些协议在网络中进行传...

terry_hding
2016/04/27
190
0
重读TCP/IP(4)之IP协议及传输

IP IP是TCP/IP协议族中最为核心的协议,所有的TCP,UDP,ICMP及IGMP数据都以IP数据报格式传输,IP协议是不可靠,无连接的,这是针对它的上层TCP来说的,不可靠指的是它不能保证IP数据能成功地到...

terry_hding
2016/05/07
332
1
TCP/IP协议头部结构体(网摘小结)

TCP/IP协议头部结构体(转) 网络协议结构体定义 全面的网络协议结构体定义 ================================================================================ IP协议 IP协议(Internet Pr...

长平狐
2013/01/06
374
0
记一次HTTP/TCP数据报的探究

探究背景:我们经常说TCP是传输层协议,IP是网络层协议,HTTP协议是应用层协议等等,那么究竟他们三者是如何融洽的工作在一起的呢?我们今天主要来实验探究一下TCP和HTTP到底是怎么结合的。 ...

yx1991523
2018/08/06
0
0
TCP/IP协议栈 头部参数

IP头部:20个字节 TCP头部:20字节 UDP头部:8字节 ICMP头部:4字节 TTL:经过一个路由器就减1,当TTL值为0时,路由器就丢弃这个包,然后发送ICMP包给源主机。 默认情况下,Linux系统的TTL值...

满小茂
2016/04/07
1K
2

没有更多内容

加载失败,请刷新页面

加载更多

Kafka实战(五) - 核心API及适用场景全面解析

1 四个核心API ● Producer API 允许一个应用程序发布一串流式的数据到一个或者多个Kafka topic。 ● Consumer API 允许一个应用程序订阅一个或多个topic ,并且对发布给他们的流式数据进行处...

JavaEdge
19分钟前
5
0
实现线程的第三种方式——Callable & Future

Callable Runnable 封装一个异步运行的任务, 可以把它想象成为一个没有参数和返回值的异步方 法。Callable 与 Runnable 类似, 但是有返回值。Callable 接口是一个参数化的类型, 只有一 个...

ytuan996
今天
8
0
OSChina 周六乱弹 —— 不要摁F了!

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @巴拉迪维 : 朴树写的词曲都给人一种莫名的失落感,不过这首歌他自己却没有唱,换成赵传这种高音阶嘶喊的确很好,低沉但却有力,老男人的呐喊...

小小编辑
今天
10
0
Android Binder机制 - interface_cast和asBinder讲解

研究Android底层代码时,尤其是Binder跨进程通信时,经常会发现interface_cast和asBinder,很容易被这两个函数绕晕,下面来讲解一下: interface_cast 下面根据下述ICameraClient例子进行分析...

天王盖地虎626
昨天
12
0
计算机实现原理专题--存储器的实现(二)

计算机实现原理专题--存储器的实现(一)中描述了一种可以记住输入端变化的装置。现需要对其功能进行扩充,我们将上面的开关定义为置位,下面的开关定义为复位,然后需要增加一个保持位,当保...

FAT_mt
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部