赞
踩
TCP/IP是一个Protocol Stack,包括TCP、IP、UDP、ICMP、RIP、TELNET、FTP、SMTP、ARP等许多协议;协议栈分为四层:从上到下应用层、传输层、Internet层(又称网际层)、网络访问层(又称网络接口层)。
应用层传输的消息称为Message,TCP/IP的应用层协议如下:
传输层协议分为TCP和UDP。PDU通过传输层加入首部后被封装为数据段segment。
TCP最多2^16个端口号,范围为0-65535;源端口号为本机客户端,随机分配的;目标端口号为服务端,每个应用层程序都要约定固定的端口。
对于服务端的端口号,0-1023只能是系统管理员账户使用,普通用户只能用1024及之后的。客户端随机端口号范围:49152-65535
确认号 = 接收报文段的序号 + 数据长度,即确认号指定了下一个报文段的数据部分的第一个字节序号
假如A和B通信,A发送"hello\n"给B,报文段位序号为2379453244,因为当前报文段数据长度为6字节,则接收方收到该报文段后,接收方应答发送方的报文段中的确认号为2379453250,表示确认已经收到前面的6字节数据,请发送下一个报文段。
而B的应答报文中的序号,代表应答字节流的第一个字节序号,逻辑与A发送信息给B是一样的,即:A下一次发生报文段的确认号 = B的应答报文序号 + 应答报文数据部分长度
这样A-B通信通过确认号,确认对方收到信息后,再给对方发送消息,形成闭环可靠的数据流。
**初始序号,ISN(Initial Sequence Number):** 当新连接建立的时候,第一个字节数据的序号称为ISN(Initial Sequence Number),即初始序号。
ISN一开始并不一定就是1。在**RFC(规定网络协议的文档)**中规定,ISN的分配是根据时间来的。当操作系统初始化的时候,有一个全局变量假设为`g_number`被初始化为1(或0),然后每隔4us加1.
当`g_number`达到最大值的时候又绕回到0.当新连接建立时,就把`g_number`的值赋值给ISN.
两次报文传输抓包试验分析:293号报文的ack表示已经收到292号报文的116个字节。
292报文:
seq:19192 len:116
293报文:
ack:19208 = 1912 +116
数据偏移占4位二进制,最大偏移量15,每一个偏移量代表4字节。所以TCP首部 最大15 * 4 = 60 字节
URG:表示本报文段中发送的数据是否包含紧急数据。后面的紧急指针字段(urgent pointer)只有当URG=1时才有效
ACK:表示是否前面的确认号字段是否有效。ACK=1,表示有效。只有当ACK=1时,前面的确认号字段才有效。TCP规定,连接建立后,ACK必须为1,带ACK标志的TCP报文段称为确认报文段
PSH:提示接收端应用程序应该立即从TCP接收缓冲区中读走数据,为接收后续数据腾出空间。如果为1,则表示对方应当立即把数据提交给上层应用,而不是缓存起来,如果应用程序不将接收到的数据读走,就会一直停留在TCP接收缓冲区中
RST:如果收到一个RST=1的报文,说明与主机的连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接。或者说明上次发送给主机的数据有问题,主机拒绝响应,带RST标志的TCP报文段称为复位报文段
SYN:在建立连接时使用,用来同步序号。当SYN=1,ACK=0时,表示这是一个请求建立连接的报文段;当SYN=1,ACK=1时,表示对方同意建立连接。SYN=1,说明这是一个请求建立连接或同意建立连接的报文。只有在前两次握手中SYN才置为1,带SYN标志的TCP报文段称为同步报文段
FIN:表示通知对方本端要关闭连接了,标记数据是否发送完毕。如果FIN=1,即告诉对方:“我的数据已经发送完毕,你可以释放连接了”,带FIN标志的TCP报文段称为结束报文段
窗口大小, Window Size:表示现在允许对方发送的数据量,也就是告诉对方,从本报文段的确认号开始允许对方发送的数据量/一次发多少个包。
累积确认:真正的TCP传输的时候不是说发一个包对方回应一个包,再发一个再回应一个,这样效率很低,通常做法法是一次发多个包,对方确认最后一个包就行了。
滑动窗口:Window Size=Num就是固定窗口,固定速率,这种不太现实。滑动窗口原理如图所示,其逻辑是,发送端先尝试一次发3个包,接收只接收了2两个,并在应答中告诉对方,我当前网络环境只能一次收2个包,即确认号Ack 3(告诉发送方下一次发送的数据的序号的同时,变相告诉发送方一次只能接收2个包);真正通信中更多的就是采用滑动窗口,根据实时情况调整发送速率。
常见选项:
最大报文段长度:Maxium Segment Size,MSS。指明自己期望对方发送TCP报文段时那个数据字段的长度。默认是536字节。数据字段的长度加上TCP首部的长度才等于整个TCP报文段的长度。MSS不宜设的太大也不宜设的太小。若选择太小,极端情况下,TCP报文段只含有1字节数据,在IP层传输的数据报的开销至少有40字节(包括TCP报文段的首部和IP数据报的首部)。这样,网络的利用率就不会超过1/41。若TCP报文段非常长,那么在IP层传输时就有可能要分解成多个短数据报片。在终点要把收到的各个短数据报片装配成原来的TCP报文段。当传输出错时还要进行重传,这些也都会使开销增大。因此MSS应尽可能大,只要在IP层传输时不需要再分片就行。在连接建立过程中,双方都把自己能够支持的MSS写入这一字段。 MSS只出现在SYN报文中。即:MSS出现在SYN=1的报文段中
窗口扩大:Windows Scaling。为了扩大窗口,由于TCP首部的窗口大小字段长度是16位,所以其表示的最大数是65535。但是随着时延和带宽比较大的通信产生(如卫星通信),需要更大的窗口来满足性能和吞吐率,所以产生了这个窗口扩大选项
时间戳: Timestamps。可以用来计算RTT(往返时间),发送方发送TCP报文时,把当前的时间值放入时间戳字段,接收方收到后发送确认报文时,把这个时间戳字段的值复制到确认报文中,当发送方收到确认报文后即可计算出RTT。也可以用来防止回绕序号PAWS,也可以说可以用来区分相同序列号的不同报文。因为序列号用32为表示,每2^32个序列号就会产生回绕,那么使用时间戳字段就很容易区分相同序列号的不同报文
TCP失序字节处理及理解?
假设主机A通过一条TCP连接向主机B上的一个进程发送数据,假定数据流由一个包含500000字节的文件组成,其MSS(最大报文段长度)为1000字节,数据流的首字节编号是0,如下图所示。该TCP将为该数据流构建500个报文段,给第一个报文段分配序号0,第二个报文段分配序号1000,以此类推,每一个序号被填入到相应TCP报文段首部的序号字段中。
假设主机A已收到主机B的包含字节0-535字节的报文段,以及另一个包含字节900-1000的报文段。由于某种原因,主机A还没有收到字节536-899的报文段。在这个例子里,主机A为了重新构建主机B的数据流,仍在等待字节536(和其后的字节)。因此,A到B的下一个报文段将在确认号字段中包含536。因为TCP只确认该流中到第一个丢失字节为止的字节,所以TCP提供的是累积确认。
主机A虽然收到了字节900-1000的报文段,但是并不会在下一个发往主机B的报文段的确认号字段中填1001,因为535后面的字节还没有得到确认,而收到的900-1000字节的报文段属于失序到达,对于失序到达的报文段的处理方法由TCP编程人员去具体实现,有两个基本选择:一是丢弃失序报文段,二是保留失序字节并等待缺少的字节以填补该间隔(这是实践中采用的方法)
为什么进入TIME-WAIT,原因是确认没有残留的未传输完成数据。
孤儿连接: 第二次挥手后,迟迟不发第三次挥手(比如突然对方网络断开了),这个时候发起断开的请求方就进入了孤儿连接状态。这种废进程状态会消耗计算机资源。
Linux防止孤儿连接长时间停留在内核中,指定了最大孤儿连接数目和孤儿连接生存时间:
/proc/sys/net/ipv4/tcp_max_orphans
/proc/sys/net/ipv4/tcp_fin_timeout
TCP三次握手和四层挥手抓包试验:
时序图,序号和确认号为抓包试验中的后三位:
三次握手和四层握手涉及发送方和接收方的状态,这些状态的专业名词叫有限状态机FSM:Finite State Machine:
有限状态机FSM:Finite State Machine:
客户端先发送一个FIN给服务端,自己进入了FIN_WAIT_1状态,这时等待接收服务端的报文,该报文会有三种可能:
只有服务端的ACK
只有服务端的FIN
基于服务端的ACK,又有FIN
TCP为上层协议提供服务,通过端口号来确认上层服务的应用协议(比如上一层的应用程序端口号为80,则这个程序为http协议),TCP/UDP协议各自的端口范围均为0-65535。
22/tcp(ssh), 80/tcp(http), 443/tcp(https)
1433/tcp(SqlServer),1521/tcp(oracle), 3306/tcp(mysql),11211/tcp/udp (memcached)
/proc/sys/net/ipv4/ip_local_port_range
TCP为上层协议提供服务,对应常见的应用层协议端口号:
22 – ssh
80 – http
21 – ftp
23 – telnet
53 – DNS
3306 – mysql
11211 – memcached
UDP为上层协议提供服务,对应常见的上层协议端口号:
53 – DNS(TCP/UDP协议,对应上层DNS服务,端口号都为53)
69 – TFTP
161 – SNMP
11211 – memcached (TCP/UDP协议,对应上层memcached服务,端口号都为11211)
linux查看本机应用程序使用了哪些端口号:cat /etc/services |grep PortNum
linux查看真的客户端随机端口号范围(所以是可以修改的):cat /proc/sys/net/ipv4/ip_local_port_range
IANA:互联网数字分配机构(负责域名,数字资源,协议分配)
异常网络状态下(丢包),TCP服务必须能够重传超时时间内未收到确认的TCP报文段。TCP模块为每个TCP报文段都维护了一个重传定时器,
该定时器在TCP报文段第一个被发送时启动;如果超时时间内未收到接收方的应答,TCP模块将重传TCP报文并重置定时器。
TCP超时重传相关的内核参数:
/proc/sys/net/ipv4/tcp_retries1,指定底层IP接管之前,TCP最少执行的重传次数。默认为3次;
/proc/sys/net/ipv4/tcp_retries2,指定放弃连接前,TCP最多可以执行的重传次数,默认15次;
TCP还有拥塞控制策略,参考标准文档RCF581
局域网应该还可以,传输性能好,有限的错误检测功能。绝大部分互联网应用都用TCP。
ICMP协议,Internet Control Messages Protocol,因特网信报控制协议。作用:测试网络是否通畅。
/proc/sys/net/ipv4/icmp_echo_ignore_all
配置项,临时关闭ICMP:echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
,这样其他服务器ping这台服务器,避免黑客攻击。ping -f -s 65507 IP
;-f
让CPU尽其所能的去ping指定的IP;-s
,修改ping时SMTP的数据包的大小,最大65507字节;通过这条命令很简单的实现网络攻击,使对方网络瘫痪。企业为了网络安全,会设置防火墙把ICMP协议禁用。ICMP协议还可以发广播:ping -b 广播地址IP
,比如ping -b 192.168.8.255
,作用:检查广播域中哪些主机网络是通的,哪些有问题
echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
1 作用:ARP协议,Address Resolution Protocol,地址解析协议。通过ARP协议,利用IP地址,查找到对应的Mac地址。
linux:arp -n; windows:arp -a
。为什么计算机配了IP及路由后,两个机器之间就可以通信了呢?
1 网络通信的时候,主机接收到的数据包首先到达物理层,然后再往数据链路层传;
2 在数据链路层首先分析数据包中的目标Mac地址是不是本机的MAC地址,如果是才接收并继续往网络层传输,不是直接抛弃;
3 而发送端发送数据的时候,开始只知道目的IP,是根据目的IP发送数据包的,并不知道目的Mac地址,数据链路层的包头怎么填目的MAC地址呢?如果不填发送的数据包将会被抛弃无法被目的主机接收。
事实上,就是通过ARP协议,利用IP地址,查找到对应的Mac地址,然后在数据报文里面写上Mac地址,就能收到了。
2 ARP协议查找Mac过程:
如果A-B隔着路由怎么办呢?
ARP协议通信的时候,会先计算目标IP在不在同一个网络里,如果不在同一个网络,就不会通过ARP广播直接查找目标主机。假设主机A(Mac_A)和主机C(Mac_C)通信,隔着路由器:
所以,ARP协议通信过程是一段一段寻找一段一段通信,在整个广播域中直到找到目的地址。
3 ARP协议应用场景理解
arping -i eth0 +ip
,可以通过指定端口,查找网络中指定的ip对应有几个Mac,如果有多个Mac地址,说明IP冲突了。场景:网络中,应用程序A:192.168.1.5和应用程序B:192.168.1.6要建立连接进行通信,描述请求建立连接的过程?
一次完整的网络请求过程
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。