TCP控制字段标志

在TCP层,有个FLAGS字段,这个字段有以下几个标识:SYN, FIN, ACK, PSH, RST, URG.
其中,对于我们日常的分析有用的就是前面的五个字段。

它们的含义是:

URG:Urget pointer is valid (紧急指针字段值有效)

SYN: 表示建立连接

FIN: 表示关闭连接

ACK: 表示响应

PSH: 表示有 DATA数据传输

RST: 表示连接重置。

   其中,ACK是可能与SYN,FIN等同时使用的,比如SYN和ACK可能同时为1,它表示的就是建立连接之后的响应,如果只是单个的一个SYN,它表示的只是建立连接。TCP的几次握手就是通过这样的ACK表现出来的。但SYN与FIN是不会同时为1的,因为前者表示的是建立连接,而后者表示的是断开连接。RST一般是在FIN之后才会出现为1的情况,表示的是连接重置。一般地,当出现FIN包或RST包时,我们便认为客户端与服务器端断开了连接;而当出现SYN和SYN+ACK包时,我们认为客户端与服务器建立了一个连接。PSH为1的情况,一般只出现在 DATA内容不为0的包中,也就是说PSH为1表示的是有真正的TCP数据包内容被传递。

  TCP产生 RST响应的情况(属于硬错误):

   四次握手不是关闭 TCP连接的唯一方法. 有时,如果主机需要尽快关闭连接(或连接超时,端口或主机不可达),RST (Reset)包将被发送. 注意在,由于RST包不是TCP连接中的必须部分, 可以只发送RST包(即不带ACK标记). 但在正常的TCP连接中RST包可以带ACK确认标记

  1. syn发送到服务器主机,但是目的端口并未运行。则产生一个ECONRFUSED错误。客户端立即返回。比如telnet 192.168.1.55 8889,条件:55主机在局域网上并且可达(也可以换成可以到达的网络ip地址),但是8889这个端口并未使用(可能服务器已经关闭),则服务器(对方主机tcp内核)发送一个rst相应给客户端,于是客户端立即关闭。 注意一下,如果输入的网络ip不可达的话,客户端将会持续发送syn,最后产生一个etimeout的错误,大概75秒左右。这个时候客户端的默认网关(192.168.1.1 211.2.2.2)因为找不到下一路由,路由器(或者再过几跳的路由器)会产生一个EHOSTUNREACH响应给客户端(注意,ENETUNREACH和EHOSTUNREACH通常被认为是一个错误,因为ENETUNREACH一般当作已过时),由于这是个软错误(有可能是网络暂时不通造成的)。客户端会重发syn直到超时。
    所以会有 telnet 192.168.1.55 8888  主机存在,但是端口未开,ECONRFUSED错误,立刻返回
             telnet 192.168.1.56 *     主机不存在,UNROUTETOHOST错误,立刻返回
             telnet 211.1.1.5    *     主机不存在,etimeout错误

  2. 最简单的情况,服务器主动发送rst给客户端关闭连接。客户端read write直接返回rst错误。

  3. 服务器收到一个不存在的连接返回rst响应。比如,服务器重启之后,先前的一个已连接的客户端毫不之情的情况下,这就是半闭连接(跟半开连接最大的不同是,半闭连接是不能使用的,半开连接可以使用)。
   此时,如果客户端read的话(接收缓冲无数据)产生一个EPEERRST错误。
如果客户端write的话且发送数据小于发送缓冲区剩余容量时,第一次write成功,第二次write或者read的时候就会产生一个EPEERRST的错误。因为write发送数据是直接把要发送的数据拷贝到内核的tcp发送缓冲区就立刻返回成功的。当然拷贝之前会先检查一下tcp连接有无错误。所以第二次发送或者接收的时候,发现连接上已经有了EPEERRST的错误,所以就返回错误(话说回来,第一次发送的数据实际上根本就没有发送成功,对方根本就没接受它)
### TCP协议中的字段及其作用 TCP(Transmission Control Protocol)是一个面向连接的、可靠的传输层协议。它通过一系列复杂的机制来确保数据能够安全、有序地到达目标设备。以下是TCP头部的主要字段及其具体功能: #### 1. **源端口号 (Source Port)** 此字段占2字节,用于标识发送方的应用程序或进程。接收方可以根据该端口将响应数据返回给正确的应用程序。 #### 2. **目的端口号 (Destination Port)** 同样占据2字节,表示接收方上的特定应用或服务对应的端口号。这使得多个不同的网络服务可以共存于同一台主机上[^3]。 #### 3. **序号 (Sequence Number)** 这是一个4字节的字段,用来标记当前数据段的第一个字节在整个会话流中的位置。这一特性允许接收者重组接收到的数据片段并检测是否有丢失的情况发生[^2]。 #### 4. **确认号 (Acknowledgment Number)** 也是由4字节组成,在建立连接之后使用。当ACK标志被设置时,这个数值代表下一个期望从对方那里接收到的数据包的位置编号,从而实现了对已成功接受到的信息部分给予反馈的功能[^5]。 #### 5. **数据偏移量 / 首部长度 (Data Offset or Header Length)** 仅需4比特即可表达,指出tcp报文中实际有效载荷之前存在多少个32bit组成了tcp头信息。由于选项的存在可能导致tcp头大小变化不定,故而引入此项说明确切尺寸。 #### 6. **保留位 (Reserved Bits)** 共有6比特,默认全设为零,预留未来扩展用途之便[^4]。 #### 7. **控制位 (Control Flags 或 FLAGS 字段)** 总长6比特,分别对应六个可能的操作指示符:URG、ACK、PSH、RST、SYN 和 FIN 。这些标志决定了如何处理关联的数据或者整个链接状态转换过程: - URG: 表明紧急指针域有效; - ACK: 确认序列号码可用; - PSH: 告诉远程系统立即推送缓冲区内的所有待传数据至更高层次; - RST: 请求终止异常关闭的连接关系; - SYN: 同步序列编号以发起新的握手动作; - FIN: 发送结束信号通知另一侧准备释放资源。 #### 8. **窗口大小 (Window Size)** 两字节宽度,告知发送方可继续传送的最大数量未获回应的数据单位数,以此达成流量调控的目的。 #### 9. **校验和 (Checksum)** 覆盖整个伪首部加上真实tcp段计算得出的一个十六进制值,旨在验证数据完整性防止错误传播。 #### 10. **紧急指针 (Urgent Pointer)** 如果设置了URG flag,则本项给出相对于seq num而言紧随其后的第一个非急迫字节所在处的距离差值。 #### 11. **选项 (Options)** 可变长度区域,主要用于协商最大分段规模(MSS),时间戳等功能增强型参数交换场合下填充必要内容。 ```python import struct def parse_tcp_header(data): src_port, dst_port, seq_num, ack_num, offset_reserved_flags, window_size, checksum, urg_ptr = \ struct.unpack('!HHLLBBHH', data[:20]) offset = (offset_reserved_flags >> 4) * 4 flags = offset_reserved_flags & 0x3F return { 'src_port': src_port, 'dst_port': dst_port, 'seq_num': seq_num, 'ack_num': ack_num, 'flags': bin(flags), 'window_size': window_size, 'checksum': hex(checksum), 'urg_ptr': urg_ptr, 'options': data[20:offset].hex() } ``` 上述代码展示了如何解析标准固定长度部分的TCP头部结构,并提取其中的关键信息。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值