Linux
Linux复习归纳10~
tcpdump和Wirshark
抓到的报文格式
第一列:时间戳,分别代表时、分、秒、微秒
第二列:网际网路协议名称
第三列:报文发送方的网际网路协议地址和端口
第四列:> (用于指向接收方)
第五列:报文接收方的网际网路协议地址和端口(有时不是端口而是协议名比如http)
第六列::
第七列:Flags标识,可能取值是[S.] [.] [P.] [F.]等(标识有SYN表示建立连接,FIN表示关闭连接,ACK表示相应,PSH表示有数据传输,RST表示连接重置,其中ACK可能与SYN、FIN等同时使用,SYN与FIN不可能同时为1,RST一般在FIN后才会出现1的情况,PSH表示有真正的tcp数据包内容被传递)
之后列是tcp协议报文头的一些变量值,比如seq为请求同步的序列号,ack是已同步的序列号,win是当前可用窗口大小,length是tcp协议报文体的长度
tcpdump抓取网站网络数据实例
- 通过tcpdump截取主机www.baidu.com发送与接收的所有数据包
tcpdump -i en0 host www.baidu.com
- 访问这个网站
wget www.baidu.com
- 此时tcpdump会出现以下包信息:
我们发现三次握手中第三次时ACK为1,其实这是相对值,我们可以通过下面命令获取ACK的绝对值:
tcpdump -S -i en0 host www.baidu.com
- 若想要看到详细的http报文,可以通过下面命令:
tcpdump -A -i en0 host www.baidu.com
关于Wireshark
关于Wireshark
Wireshark用于捕获机器上某块网卡的网络包(如果一个机器有多个网卡,可以指定其中一个网卡)。出于安全考虑,它不可以修改封包的内容或者发送封包。它也不能解密https(也就是所看不懂https中的内容,如果只处理http和https,可以考虑Fiddler)
用处
- 抓包来分析测试自己的软件
- 用wireshark来检查网络问题
- socket编程会用wireshark来调试
流程
- 先选定需要捕获哪个网卡的网络包
- 主界面中从上往下依次是显示过滤器(用于过滤)、封包列表(显示捕获到的封包)、封包详细信息、16进制数据、地址栏(杂项)
- 右键想要查找的报文->跟踪流->tcp流即可
关于过滤器
封包列表中会有大量的冗余无用信息,我们可以利用过滤器将其过滤掉。过滤器有两种,一种是显示过滤器(主界面最上面),另一种是捕获过滤器(设置捕获的数据类型,在捕获->捕获过滤器中设置)
过滤分为协议过滤(比如tcp、udp等)、ip过滤(比如ip.src192.168.1.30代表显示原地址为192.168.1.30的数据报,ip.dst192.168.2.31代表显示目标地址为192.168.2.31的数据包)、端口过滤(比如tcp.port80代表显示端口号为80的,tcp.srcport80代表源端口号为80的)、http模式过滤(比如http.request.method=="GET"代表只显示get方法),它们可以通过逻辑运算符连接(AND/OR)
关于封包详细信息
封包详细信息最多有5行,分别是Frame(物理层的数据帧概况)、Ethernet II(数据链路层以太网帧头部信息)、Internet Protocol Version 4(网络层IP包头部信息)、Transmission Control Protocol(传输层的数据段头部信息,此处是TCP)、Hypertext Transfer Protocol(应用层的信息,此处是HTTP协议)
其中对于传输层的详细信息来说,source port为源端口,destination port为目的端口,sequence number为序列号,acknowledgment. number为确认号,Header Length为报头长度,flags为标志位,window size value 为窗口大小,checksum为校验和,
关于三次握手四次挥手
三次握手
- 由客户端向服务器端发起TCP连接请求(同步序列编号SYN置为1,发送序号Seq为一个随机数(避免黑客通过伪装发送数据报)假设为X)
- 服务器端接收到连接请求(同步序列编号SYN置为1,并将确认序号ACK置为X+1,然后生成一个随机数Y(与X同理)作为发送序号Seq)
- 客户端对接收到的确认进行确认(将确认序号ACK置为Y+1,然后将发送序号Seq置为X+1)
四次挥手
双方完成数据传输后就需要断开连接,由于tcp属于全双工通道,因此可以在一条tcp连接上相互传输数据,因此在一方失去发送数据的能力时,存在一个半关闭的状态,使得其还可以接收数据。这时就需要四次挥手
- A向B发起断开连接请求(关闭序列编号FIN置为1,发送序号Seq假设为X),A进入FIN-WAIT-1状态;(第一次挥手)
- B收到断开请求后向A发送确认(ACK置为1,发送序号Seq假设为Y,然后ack为X+1),然后进入CLOSE-WAIT状态;(第二次挥手)
- A收到B的确认后,进入FIN-WAIT-2状态(半关闭状态)
- 过一段时间后,B向A发出断开连接请求(ACK置为1,关闭序列编号FIN置为1,发送序号Seq假设为Z,然后ack为X+1),然后进入LAST-ACK状态 (第三次挥手)
- A接收到请求后发送确认(ACK置为1,发送序号Seq为X+1,然后ack为Z+1),进入TIME-WAIT状态,等待2MSL之后进入CLOSED状态 (第四次挥手)
- B收到确认后进入CLOSED状态
问题一:为什么至少三次挥手
1. tcp是一个全双工通道,它建立连接的基础是双方都需要确保自己具有接收对方信息和给对方发送信息的能力,而三次则是理论上的最小值(第一次服务端能确认自己有接收能力,客户端有发送能力;第二次客户端能确认客户端和服务端都有接收和发送能力;第三次服务端能确定服务端和客户端都有接收和发送能力)
2. 客户端向服务端发送一个请求,服务端收到后会返回一个确认报文。而此时客户端断开连接,服务端却单方面认为连接成功,而等待客户端的动作,从而导致服务端开销增大
问题二:第四次挥手为什么需要等待2MSL
- 确保A最后发送的确认能够到达B(如果B收不到会超时重传FIN给A),至于2MSL能够保证A游足够的时间去再次发送确认
- 如果没有等待2MSL直接到close状态。那么当A再次向B发起连接请求,若该请求报文的包比上一次连接的最后一次挥手确认的包更早的到达B。那么B会以为这个连接为失效连接。等待2MSL可以尽量避免这种情况的出现
问题三:为什么断开连接请求报文只有三个,而不是4个?
在tcp连接过程中,确认的发送有一个延时,一端在发送确认的时候将等待一段时间。如果在这段时间内自己也有数据要发送,那就跟确认一起发送,如果没有则单独发送。(服务端先断开连接,客户端在确认的时延内有也有请求断开连接需要发送,于是和确认一起发送,因此只有三个数据报)
如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢