如TCP前篇所述,我们已初步了解了回退N步(GBN,又名滑动窗口)协议 和选择重传协议(SR)。接下来则是直接与TCP对线,并了解TCP为了我们便利的生活付出了多少艰辛!
一. TCP 报文段结构
源端口号 & 目的端口号:各16位,大小在0~65535之间。其中0~1023范围的端口是周知端口号,保留给诸如HTTP(端口号 80),FTP(端口号 21)之类的周知应用层协议的。当我们开发一个简单应用程序的时候,必须为其分配一个端口号。
序号(seq) & 确认号(ack):如前篇所述,实现发送方和接收方可靠传输的必要手段。
首部长度(也称为数据偏移):以4个字节为单位,由于选项字段,TCP首部长度是不一定的(通常选项字段为空,也就是通常首部长度为20字节,那么 首部字段的值为 5。--> 5 * 4 字节 = 20 字节)。
标志字段:6位
URG:指示报文段存在着“紧急数据”,数据由紧急指针字段指出;
ACK:用于指示确认号字段是否有效(因为发送方的确认号字段是无效的);
PSH:指示接收方应立即将数据交付给上层;
RST & SYN & FIN:用于TCP连接建立与拆除!
接收窗口字段:用于流量控制,指示接收方愿意接收的字节数量;后面会有讨论
检验和字段:用于确定报文段从源到达目的地移动时候,其中比特是否发生改变,也就是检查该报文段中是否出现差错;计算原理:
发送方:
将报文段中的所有比特按16位一组相加,溢出则回卷(就是溢出 位加 在最后一位),得到结果取反码,存放到检验和字段;
接收方:
按照上面方法分组计算(含检验和字段),如果没有出现错,结果应 该为1111 1111 1111 1111
原理大致为:c = a + b;检验和字段:^c
接收方检验:a + b + ^c = c + ^c = 1 (可以用 1011 与 0100 检验)
选项字段(options field):用于发送方和接收方协商最大报文段长度(MSS),或者在高速网络环境下用作窗口调节因子使用!
二.相关细节
1.序号与确认号
序号是建立在传送的字节流上,而不是建立在传送的报文段的序列之上(也就是说根据字节数编号而非根据报文段的个数编号),一个报文段的序号是该报文段数据首字节的字节流编号:
假如一文件有50 0000字节大小,MSS为1000字节,数据流的首字节编号为0,那么第一报文序号为0;
第二个报文段携带数据首字节字节流编号为:1000,故第二个报文段序号为:1000,,,一共 500个报文段
确认号是接收方期望发送方发送的下一个字节的序号;
情景:
如发送方ack = 79 表示,我想要序号为79的报文,搞快点~
(注意上例两个主机互发消息,且为一个字节,容易造成序号相关误解)
2.TCP 连接建立之三次挥手
先设想这样情景:假如你要拜访一个许久未见的朋友,为防止“小扣柴扉久不开”,那么最稳妥的方法就是先给他打电话,传达你要拜访他的意愿;然后他得知你的意愿,倘若方便的话,就会告诉你可以来,并吩咐家里准备酒菜等相关事宜;最后你确定可以到他家,那么你也可以洗脸锁门了,而且可以带上礼物去... ...
因此建立可对照如下:
第一步:客户端向服务器发送一个特殊的TCP报文段,此报文段不包含应用层数据。但是在报文段首部中的SYN位被置为1(故又称SYN报文段),另外,客户TCP也会随机选择一个初始序号(client_isn)并放置在序号字段。
第二步:一旦包含TCP SYN报文段的IP数据报到达服务器治具,服务器从中提取到TCP SYN报文段。然后服务器为TCP连接分配缓存和变量,并向客户TCP发送允许连接的报文段(称为 SYNACK 报文段):SYN位 和 ACK位 设置为1;服务器TCP选择自己的报文序号(server_isn);服务器TCP将确认号设为 client_isn + 1(表示期望收到序号为(client_isn + 1)的字段 )。相当于向客户端表明,我同意建立连接。
第三步:客户端收到SYNACK报文段之后,也要给该连接分配缓存和变量。然后客户端开始向服务器发送另外一个报文段,对服务器同意连接表示确认:SYN位设置为 0;序号设置为 client_isn + 1; 确认号设置为:server_isn + 1。当然,此步骤可以在报文段负载中携带客户到服务器的数据。
3.TCP连接销毁之四次挥手
联想情景:
你在朋友家酒过三巡,你觉得时候不早该回家了,你便向朋友告辞;
然后朋友发现天色已晚,便不留你暗示同意你走了;
然后朋友收拾一下看你有没有东西落下,确认你可以走了并嘱咐你到家记得打电话报平安;
你马上到家的时候,向朋友打电话说“我到家了”(打不通的时候经过一段时间再打一次),最终结束了一天的访友工作!
TCP四次挥手与上类似:
客户应用程序发出关闭连接的命令,于是客户TCP向服务器进程发送一个特殊的TCP报文段:FIN标志位设置为1;
服务器接收到报文段时候,向客户端发送了一个确认报文段;
然后服务器发送一个终止报文段,FIN位设置为1;
最后客户端接收到终止报文段并对其确认;
番外:SYN洪泛攻击
服务器接收到一个SYN时候,会初始化连接变量和缓存;然后回复SYNACK报文段进行响应;
如果客户不发送第三次握手动作,最终(一分钟之后)服务器将终止该半开连接并回收资源;
这种TCP连接管理协议为经典的DoS攻击即SYN洪泛攻击(SYN flood attack)提供了环境:攻击者大量发送TCP SYN报文段而不完成第三次握手的步骤,但服务器不断地为这些半开连接分配资源导致服务器的资源被耗尽。
防御方式:SYN cookie,被部署在大多数主流操作系统中
当服务器接收到一个SYN报文段时,它不会生成一个半开连接,同时,服务器生成一个初始TCP序号,该序号是SYN报文段的源 & 目的IP地址 以及端口号 还有 该服务器知道的秘密数的一个复杂函数。这种精心制作的初始序列号被称为“cookie”,服务器发送具有这种初始序列号的SYNACK分组;
如果用户是合法的,则他它将返回一个ACK报文段。当服务器收到该ACK,需要验证该ACK是否与前面发送的某些SYN相对应(确认号 = cookie + 1)。
如果用户是非法的或者并没有回复一个ACK报文段,那么服务器也没有损失,因为它还没有为此半连接分配资源。