- 1位表示1bit,除去任选字段(选项和数据)共160bit也就是20字节
- 源端口号和目的端口号用于寻找发端和接收端【源端口+源IP地址+目的端口+目的IP地址唯一确定一个TCP连接】
- 序号用来标识从TCP发送端向接收端发送的数据字节流,他是32bit的无符号数,到达2的32次方-1后又从0开始
- 确认序号是上次已成功收到数据字节序号加1【只有ack标识是1时,他才有效】
- 首部长度标识TCP包首部实际长度,它的单位是32bit【假如数字是6,那么表示头部实际长度是 4字节*6=24字节,由于首部长度只有4bit,最大数为15,因而最多有15*32bit=480bit=60字节】
- URG置为1表示紧急指针有效
- ACK置为1表示确认序号有效
- PSH置为1表示接收方应该尽快将这个报文段交给应用层
- RST置1表示重建连接
- SYN置1用来发起连接
- FIN置1表示发端完成发送任务
- 窗口大小是TCP用来做流量控制
- 校验和覆盖TCP的首部和TCP数据,它一定由发端计算存储,收端验证
- 紧急指针是一个正偏移量,和序号字段中的值相加表示紧急数据最后一个字段的序号
- 常见可选字段如MSS(Maximim Segment Size 最长报文大小),用来标识本端能接收的最大长度的报文段
真实tcp报文怎么看?
以下报文为TCP建立和终止的报文示例
完整格式如下:
报文序号 报文产生时间(与上次报文的时间间隔) 源地址.端口号 > 目的地址 : 标识 分组序号:确认序号(报文段中字节数) 窗口大小 接收的最大报文长度
- svr4.1037 > bsdi.discard 表示源地址的某个端口到目的地址
- S是SYN标志,表示发起连接 ;F是FIN标志,表示发送端发送完数据;. 表示(SIN,FIN,RST,PSH)这四个标识都是0
- 1415531521:1415531521(0) 表示分组的序号是1415531521,报文段中的数据字节数为0
- ack后跟着的数字串是确认序号,它只有首部标识置为1才有用
- win 4096表示窗口大小
表示发送端能接收的最大报文长度
默认情况下tcpdump输出只显示SYN报文段的完整序号,其它位置显示偏移量
tcpdump怎么用?
常用参数解析
-X :用16进制显示具体内容
-n:显示IP,不转换域名
-s 0:尽可能多的展示内容
-vvv: 展示详细内容
-i eth1:监听eth1网络
tcp :监听协议类型
dst port 8500:8500端口接收的数据
-A:acsii显示内容
抓取当前机器上的post请求 sudo tcpdump -i eth1 -X -vvv -n -s 0 'tcp dst port 8500 and tcp[(tcp[12]>>2):4] = 0x504f5354'
比如我想获取post请求的原始IP可以用 sudo tcpdump -i eth1 -A -vvv -n -s 0 'tcp dst port 8500 and tcp[(tcp[12]>>2):4] = 0x504f5354' | grep 'X-Forwarded-For'
抓取当前机器上的get请求 sudo tcpdump -i eth1 -X -vvv -n -s 0 'tcp dst port 8500 and tcp[(tcp[12]>>2):4] = 0x47455420'
上面用到的tcp中括号相关内容是指tcp过滤,字节范围表达: proto [ expr : size ] photo表示协议 expr 表示与指定协议开头相关的字节偏移量;如只查看fin包 tcpdump -i
“tcp[tcpflags] & (tcp-fin) !=0”
TCP协议从那些方面保证可靠性的?
- 应用数据被分割成TCP认为最适合发送的数据块
- 发送一个报文段(TCP传递给IP信息的单位)后启动定时器,如果无法及时收到确认,重发报文
- 收到报文后,推迟几分之一秒发送确认
- 提供首部和校验和,校验和出错不确认收到此报文,引发重发
- 必要情况TCP会对收到的数据重排序,将正确的顺序交给应用层
- 接收端会丢弃重复的数据
- 本身能做流量控制
附录
把书读薄(TCP/IP详解 卷一 第十七章)