TCP头分析+面试题
一、测试程序
我们先用python来写两个测试脚本,非常简单,看代码:
服务端:
from socket import * def accept():
sock = socket(AF_INET, SOCK_STREAM, 0)
sock.bind(("127.0.0.1", 5000))
sock.listen(5)
while True:
pass if __name__ == "__main__":
accept()
客户端:
from socket import * def connect():
sock = socket(AF_INET, SOCK_STREAM, 0)
sock.connect(("127.0.0.1", 5000)) if __name__ == "__main__":
connect()
1)服务端只是简单的监听连接,什么事都不做,连关闭都没有
2)客户端只管连接服务端,什么事都不做,也没有关闭
3)这两个程序都将运行是在同一物理机器
二、TCP三次握手
我们先运行服务端,此时服务端没有任何通信数据,我们再运行客户端,由于发生了connect,此时就发生了TCP的三次握手,我们来看下握手的数据,这里我使用的工具是commview
上图显示了这三次握手的数据,可以看到,同一台机器上的回路通信,Src Mac 与 Dest Mac 显示的只是端口不一样,(前面4个字节是网卡地址,后两个字节是端口号),但网卡地址不是物理机器上的网卡地址,这是回路的Mac地址。Dest Port 是5000,这是我们监听的IP端口。Src Port是3877,这个是随机的IP端口。当客户端发生connect时,操作系统随机一个没有被使用过的IP端口供客户端使用。
我们来看下选中的第一行,具体的内容:
上图展示了第一次握手的具体数据,这是TCP/IP协议的头部信息。
面试题一:同一台机器上的网络通信,在数据包里,MAC地址是多少?是网卡实际MAC地址吗?
1、前6个字节,00 00 00 00 是目标网卡的地址, 00 02 是目标网开放的端口
2、7~12字节,00 00 00 00 是源网卡的地址,00 01是源网卡开放的端口
3、13~14字节,08 00是以太网类型,这里是IPV4网际协议,如果是IPV6则是86 DD,ARP 是08 06
以上14个字节,我们称为以太头,就是上图里红色部分
面试题一答案:不是实际地址,是00 00 00 00,是操作系统虚拟出来的网卡地址
面试题二:一个数据包在网络中,找不到目标机器,会发生什么事?会一直存在吗?
面试题三:TCP/IP协议,有地址和端口,请问,端口是谁的?TCP的,还是IP的?
4、第15个字节,45,其中4,表示IP协议版本号,即IPV4,5表示IP协议头部长度,(要注意的是,这个数据的单位是32位,也就是4个字节),所以这里的5其实表示的是20,就是说IP头有20个字节长。
5、第16字节,是区分服务,最常见的是IP电话
6、17~18字节,00 28,2 * 16 + 8 = 40个字节,这个表示整个TCP/IP协议的总长度,不包括以太头。
7、19~20字节,00 00 ,ID标识,表示这个数据包的ID,相同ID的数据包将被视为一个包,也就是说,当发生拆包时,用这个ID就能把包整合成一个正确的包。
8、21~22字节,00 00,标志(3位) + 帧位移(13位)。与上面的ID共同作用,相同的ID在整合成一个包时,帧位移标识这个帧应该放在包的哪个位置。标志表示后面是否还有数据帧。
9、第23字节,40,这个是生存时间,意思是,这个数据包在网络中的生存多久,如果没有被正确接收,当这个包存在时间超过这个生存时间时,这个包将被丢弃,这可以用来防止网络短路而造成数据包拥塞。
10、第24字节,06,这个是协议编号,告诉目标机器,我这个数据包的内容使用什么协议来承载。
11、25~26字节,7C CE,这个是checksum,校验和。有兴趣的童鞋可以网上参考一些checksum算法的文章。看看这个字段是怎么校验IP头是否正确。
12、27~30字节,7F 00 00 01是源IP地址,127.0.0.1
13、31~34字节,7F 00 00 01是目标IP地址127.0.0.1
以上20个字节,我们成为IP头。其IP地址的表示与以太头的表示顺序相反,以太头先目标MAC地址,再源MAC地址,IP头是先源IP地址,再目标IP地址。而且,IP头并不包括端口号。IP头有点复杂。但实际用到的不多。
面试题二答案:数据包存在时间超过生存时间时,会被丢弃,不会一直存在。
面试题三答案:端口是TCP的。
面试题四:TCP发送的序号与应答序号有什么关系?是一样的吗?
面试题五:如果我要让对方的QQ下线,该怎么做?
14、35~36字节,0F 25,这个是源端口号,0x0F25 = 3877
15、37~38字节,13 88,这个是目标端口号,0x1388 = 5000
16、39~42字节,00 00 00 00,这个是TCP顺序号,用于使TCP进行可靠传输。当发出一段报文时,序列号就+1
17、43~46字节,00 00 00 00,这个是TCP应答号,用于告诉目标机器,我这段报文,应答的是你发过来的哪一段顺序号报文。这个应答的编号,是顺序号+1。
18、47字节,50,这个表示TCP头部的长度,同样的,这里的5表示20字节,以32位为单位。
19、48字节,02,这个字节是TCP的6个标志位,也叫控制位。只使用后6位,02 = 0000 0010,各位的意义如下:
URG:1,紧急指针有效,0,紧急指针无效
ACK:1,确认号有效,我是应答包。0,确认号无效,我不是应答包
PSH:接收方应该尽快将这个包发送到应用层。
RST:重建连接,表示之前这个连接发生问题了,重新建立连接
SYN:发起一个连接
FIN:释放连接
20、49~50字节,40 00,窗口大小,用于流量控制,比如,发送端速度很快,接收端速度很慢,就没必要傻傻的一直快速发送。
21、51~52字节,00 00,TCP的checksum。
22、53~54字节,紧急指针。我不懂,这个我真不懂,我做了那么久得行为审计,从来没有关注过这个东东,我搞懂了再补上。。。。。
面试题四答案:应答序号是发送序号+1,不一样。
面试题五答案:向对方的机器发送一个FIN包
面试题六:为什么TCP协议是三次握手,不是两次,也不是四次?
我们再来看三次握手接下去的两次握手
验证序号:图中下划线红色部分,服务端首次发送,所有是00 00 00 00,服务端应答客户端序号00 00 00 00的数据,所以是00 00 00 01,图中蓝色部分。第48字节位12,即00010010,是ACK + SYN
验证发送:00 00 00 01, 00 00 00 01都是对的,flag为10 = 00010000 = ACK
面试题六答案:三次,可以解释为,双发都知道对方的存在。两次,只能是我发送的东西,对方能收到,但对方却不知道他发送的东西,我能不能收到。三次刚好,四次冗余
二、有数据的传输过程
先对程序进行改造,如下:
服务端:
from socket import * def accept():
sock = socket(AF_INET, SOCK_STREAM, 0)
sock.bind(("127.0.0.1", 5000))
sock.listen(5)
while True:
cltSock = sock.accept()
print(cltSock)
data = cltSock[0].recv(128)
print(data)
break if __name__ == "__main__":
accept()
客户端:
from socket import * def connect():
sock = socket(AF_INET, SOCK_STREAM, 0)
sock.connect(("127.0.0.1", 5000))
sock.send(str.encode("123")) if __name__ == "__main__":
connect()
面试题七:用户发送的数据,TCP/IP如何知道用户发送了多长的数据?
我们运行程序,然后看抓包,如下:
可以看到,多了一个数据包,这个数据包最后还有我们发送的数据“123”,看图中红线部分,它是17~18字节,表示TCP/IP协议总长度,2B = 2*16+11=43,减去IP头20, TCP头20,就能得出3个用户自己发送的数据。
面试题七答案:TCP/IP只记录了整个数据包的总长度,根据总长度,减去IP头和TCP头,得出用户发送的数据长度
三、结束会话
同样的,我们改造一下程序,如下:
服务端:
客户端:
今天时间不够,不能再写了,明天再继续写,敬请期待~~~~
TCP头分析+面试题的更多相关文章
- HTTP协议及其请求头分析
HTTP协议及其请求头分析 HTTP协议及其请求头分析 众所周知,Internet的基本协议是TCP/IP协议,目前广泛采用的FTP.Archie Gopher等是建立在TCP/IP协议之上的应用 ...
- ip头、tcp头、udp头详解及定义,结合Wireshark抓包看实际情况
公司的同事们在分析网页加载慢的问题,忽然使用到了Wireshark工具,我就像发现新大陆一样好奇,赶紧看了看,顺便复习了一下相关协议.上学时学的忘的差不多了,汗颜啊! 报文封装整体结构 mac帧头定义 ...
- PE文件学习系列二 DOS头分析
合肥程序员群:49313181. 合肥实名程序员群 :128131462 (不愿透露姓名和信息者勿加入)Q Q:408365330 E-Mail:egojit@qq.com PE文件结 ...
- JPEG概述和头分析(C源码)
原创文章,转载请注明:JPEG概述和头分析(C源码) By Lucio.Yang 部分内容来自:w285868925,JPEG压缩标准 1.JPEG概述 JPEG是一个压缩标准,又可分为标准 JPE ...
- 基于byte[]的HTTP协议头分析代码
smark 专注于高并发网络和大型网站架规划设计,提供.NET平台下高吞吐的网络通讯应用技术咨询和支持 基于byte[]的HTTP协议头分析代码 最近需要为组件实现一个HTTP的扩展包,所以简单地实现 ...
- DOS头分析
DOS头分析 PE文件结构综览: 首先上图片: 看到上面的图片可以清晰的看到PE结构复杂结构式什么样子的.有DOS首部,PE头部,PE节表,很多的表块,最后就是一些调试信息. DOS头由DOS 'MZ ...
- IP头,TCP头,UDP头,MAC帧头定义(转)
源:IP头,TCP头,UDP头,MAC帧头定义 一.MAC帧头定义 /*数据帧定义,头14个字节,尾4个字节*/ typedef struct _MAC_FRAME_HEADER { ]; //目的m ...
- IP头、TCP头、UDP头详解以及定义
一.MAC帧头定义 /*数据帧定义,头14个字节,尾4个字节*/typedef struct _MAC_FRAME_HEADER{ char m_cDstMacAddress[6]; //目的m ...
- 使用wireshark抓取TCP包分析1
使用wireshark抓取TCP包分析1 前言 介绍 目的 准备工作 传输 创建连接 握手 生成密钥 发送数据 断开连接 结论 前言 介绍 本篇文章是使用wireshrak对某个https请求的tcp ...
随机推荐
- 修改cmd的字体
通常打开的cmd默认的字体比较小,字体只有宋体和新宋体两种,如果要修改,需要通过修改注册表才行. 打开regedit后,找到如下路径HKEY_LOCAL_MACHINE\SOFTWARE\Micros ...
- Thinkphp中distinct的用法
Thinkphp中distincat的用法 TP中distinct()的用处主要是去除重复的值 在Thinkphp手册中也详细说明了(链接:http://document.thinkphp.cn/ma ...
- android后台截屏实现(1)--源码编译
前段时间接到任务要实现后台截图并上传的功能,在网上查了好久,发现遇到这类问题的人还不少.经过一番对比后发现还是修改并编译源码中的screencap类然后通过JNI来调用这种方法比较可靠,而其他的在ja ...
- [ES6] Objects create-shorthand && Destructuring
Creating Object: Example 1: let name = "Brook"; let totalReplies = 249; let avatar = " ...
- 关于在xp(sp3 专业版)下安装sql2005开发版图解
今天我在xp上安装sql2005,搞了一上午也没有搞好,最终自己还是搞好,也装了,也卸载了!这里就总结一下,让以后用sql2005的朋友能有个参考!我也是自己在GOOGLE上搜索的! 转自:http: ...
- 结合tcpdump命令对traceroute深入分析
昨天突然被问到traceroute的原理,一时竟也说不出来,有些命令平时虽然经常在用,但实际原理确并不了解,趁这次机会就来梳理一下. traceroute:是网络诊断中,用来分析IP包经过那些路由的命 ...
- Spinner( 微调) 组件
本节课重点了解 EasyUI 中 Spinner(微调)组件的使用方法,这个组件依赖于ValidateBox(验证框)组件. 一. 加载方式Spinner(微调)组件是其他两款高级微调组件的基础组件, ...
- ORA-25153: Temporary Tablespace is Empty解决方法
SQL> @/tmp/4.txt create table huang_1 (deptno number,dname varchar2(19),loc varchar2(20)) * ERROR ...
- iOS_SN_CoreData数据迁移
最开始使用CoreData的时候碰到一个问题,就是当增加一个字段的时候再次运行APP会发生崩溃,一开始不知道什么原因,只知道是里面的表结构发生改变,就重新删掉APP再次安装是可以运行的,这样调试完后觉 ...
- spring 配置文件 引入外部的property文件的两种方法
spring 的配置文件 引入外部的property文件的两种方法 <!-- 引入jdbc配置文件 方法一 --> <bean id="propertyConfig ...