iOS常见问题汇总

网络编程 - TCP/IP协议

2018-10-25  本文已影响3人  darrenW

之前简单的通过TCP/IP模型介绍了网络编程,这篇主要介绍TCP/IP协议。
TCP/IP协议其实是一个协议簇,其中比较重要的有SLIP协议、PPP协议、IP协议、ICMP协议、ARP协议、TCP协议、UDP协议、FTP协议、DNS协议、SMTP协议等。这里我们主要介绍几个常见的协议。

一、IP协议

IP协议(Internet Protocol),又叫网际协议,它解决了多个局域网互通的问题,提供不可靠、无连接的数据报传送服务。

1.IP首部

IP首部.png

现在是看图说话时间(捡重要的说)。

二、ICMP协议

ICMP(nternet Control Message Protocol),Internet控制报文协议,从技术角度来说,ICMP就是一个“错误侦测与回报机制”,其目的就是让我们能够检测网路的连线状况﹐也能确保连线的准确性﹐其主要功能包括,确认 IP 包是否成功送达目标地址,通知在发送过程当中 IP 包被废弃的具体原因,改善网络设置等。

三、TCP协议

TCP协议(Transmission Control Protocol),传输控制协议,位于传输层。它提供一种面向连接的、可靠的字节流服务。

其实我觉得Halfrost总结的很好:TCP就是通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输。

1.TCP首部

TCP首部.png

如果不计任选字段,它通常是20个字节。
依然进入看图说话环节:

2.TCP三次握手、四次挥手

2.1三次握手

TCP三次握手.png

简单来说过程就是这样的:

  1. 客户端首先向服务端发送一个SYN包和一个随机序列号 J
  2. 服务端收到后会回复客户端一个 SYN-ACK 包以及一个确认号(用于确认收到 SYN)J+1,同时再发送一个随机序列号 K
  3. 客户端收到后会发送一个 ACK 包和确定号 K+1 给服务端

我们看一个例子:

 % sudo tcpdump -c 3 -i en3 -nS host 23.63.125.15
18:31:29.140787 IP 10.0.1.6.52181 > 23.63.125.15.80: Flags [S], seq 1721092979, win 65535, options [mss 1460,nop,wscale 4,nop,nop,TS val 743929763 ecr 0,sackOK,eol], length 0
18:31:29.150866 IP 23.63.125.15.80 > 10.0.1.6.52181: Flags [S.], seq 673593777, ack 1721092980, win 14480, options [mss 1460,sackOK,TS val 1433256622 ecr 743929763,nop,wscale 1], length 0
18:31:29.150908 IP 10.0.1.6.52181 > 23.63.125.15.80: Flags [.], ack 673593778, win 8235, options [nop,nop,TS val 743929773 ecr 1433256622], length 0

第一行
client -> server
左面是发送时间18:31IP代表的是这些都是 IP 协议数据包。
10.0.1.6.52181 > 23.63.125.15.80,代表源和目标端的 IP 地址+端口。比如10.0.1.6.5218110.0.1.6是IP地址,52181是端口号。
Flags表示 TCP 报文段 header 信息中的一些缩写标识。S代表 SYN. 代表ACKP代表PUSHFFIN
1721092979是随机号seq
第二行
server -> client
前面几个就不多做说明,Flags [S.],表示报文段 header中带有SYNACK
ack1721092980,即第一行的seq+1seq673593777
第三行
client -> server
客户端接收到信息后,发送Flags [.],报文段 header中ACK
ack673593778,即第二行的seq+1

2.2四次挥手

TCP四次分手.png
  1. 客户端要断开连接了,向服务器发送FIN信号,告诉它我的数据发送完了,但是如果你有数据,我还可以接受,然后进入FIN_WAIT_1状态
  2. 服务器接确认FIN包后,发送一个ack确认包,告诉客户端我已接收到信息,但还没有做好关闭准备。发送完毕后,服务器端进入 CLOSE_WAIT状态,客户端接收到这个确认包之后,进入 FIN_WAIT_2状态,等待服务器端关闭连接。
  3. 服务器端准备好关闭连接时,向客户端发送FIN包,要断开连接。然后进入服务器进入LAST_ACK状态。
  4. 客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入 TIME_WAIT状态,等待可能出现的要求重传的ACK包。服务器端接收到这个确认包之后,关闭连接,进入CLOSED状态。等过了一定时间后,客户端没有收到服务器的ACK包,就知道已经断开连接,进入CLOSED状态。

2.3为什么要进行三次握手?

通常我们会觉得,客户端告诉服务器,我要和你握手了,然后服务器告诉客户端,我知道了,这样就可以了。为什么要多客户端再给服务器确认一遍呢?
这是因为我们现实生活中的网络是复杂的,TCP数据在传输的过程中,很有可能会出现延迟到达或者重发的情况。我们在之前谈到TCP的可靠性时,说到当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。这个时候TCP首部的序列号是相同的。
如果因为网络问题,第二个SYN包提前到达,在连接结束后第一个SYN包才到,服务器又会发一次ACK建立连接。此时服务器建立了连接,客户端没有连接,从而导致服务端建立了一个空的连接,浪费资源。
如果是三次握手,客户端再次收到相同的ACK时,会丢弃这个包,不向服务端发送ACKack,从而避免了空连接。

2.4为什么进行四次挥手

因为TCP是双全工模式,即可以同时发送和接收数据,两条通道是完全独立的。客户端向服务器挥手关闭的时候,服务器会继续传送之前没有传完的数据。在二三挥手之间,多了一个数据传送的过程,这也是为什么ACKFIN不能同时发送的原因。

3. SYN攻击

3.1 SYN攻击是什么

在三次握手过程中,服务器发送SYN-ACK之后,收到客户端的ACK之前的TCP连接成为半连接(half-open connect)。此时服务器处于SYN_RCVD状态。当收到ACK之后,服务器才能转入ESTABLISHED状态。
SYN攻击指的是,攻击客户端在短时间内伪造大量不存在的IP地址,向服务器不断发送SYN包,服务器回复确认包,并等待客户的确认。由于源地址是不存在的,服务器需要不断地重发直至超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,导致目标系统运行缓慢,严重会造成网络堵塞甚至系统瘫痪。
SYN攻击是一种典型的DoS/DDoS攻击。

3.2 如何检测SYN攻击

检测SYN攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以使用系统自带的netstats命令来检测 SYN 攻击。

3.3 如何防御SYN攻击

SYN攻击不能完全被阻止,除非将TCP协议重新设计。我们所做的是尽可能的减轻SYN攻击的危害,常见的防御 SYN 攻击的方法有如下几种:

4. TCP KeepAlive

TCP 通信双方建立交互的连接,但是并不是一直存在数据交互,有些连接会在数据交互完毕后,主动释放连接,而有些不会。交互双方出现死机、异常重启等情况都不会使TCP连接及时正常释放,造成端系统资源的消耗和浪费。为了解决这个问题,在传输层可以利用 TCP 的 KeepAlive 机制实现来实现。主流的操作系统基本都在内核里支持了这个特性。
TCP KeepAlive 的基本原理是,隔一段时间给连接对端发送一个探测包,如果收到对方回应的 ACK,则认为连接还是存活的,在超过一定重试次数之后还是没有收到对方的回应,则丢弃该 TCP 连接。
但TCP KeepAlive 是有局限。首先 TCP KeepAlive 监测的方式是发送一个 probe 包,会给网络带来额外的流量,另外 TCP KeepAlive 只能在内核层级监测连接的存活与否,而连接的存活不一定代表服务的可用。例如当一个服务器 CPU 进程服务器占用达到 100%,已经卡死不能响应请求了,此时 TCP KeepAlive 依然会认为连接是存活的。因此 TCP KeepAlive 对于应用层程序的价值是相对较小的。需要做连接保活的应用层程序,例如 QQ,往往会在应用层实现自己的心跳功能。

四、UDP协议

UDP协议(User Datagram Protocol),用户数据报协议。UDP 不提供复杂的控制机制,利用 IP 提供面向无连接的通信服务。传输途中即使出现丢包,UDP 也不负责重发,甚至当出现包的到达顺序乱掉时也没有纠正的功能。UDP 面向无连接,它可以随时发送数据。

1.UDP首部

UDP首部.png

2.TCP和UDP区别

五、DNS协议

通常我们去请求一个网址输入的是https://github.com这种形式,但这并不是IP地址。那我们怎么去寻找他的地址呢?这时候就需要DNS。
DNS域名系统是一种用于TCP/IP应用程序的分布式数据库。我们向DNS服务器发送一个DNS数据包,然后DNS服务器做出响应告诉我们github的IP地址是192.30.253.113
目前有很多DNS服务器,比如google的8.8.8.8,阿里的223.5.5.0,百度的180.76.76.76
有时候我们会遇到DNS被污染的情况,这个时候我们就没办法去请求某一个网页。一个小技巧:在使用MAC的情况下,在跳转路径输入:/private/etc/,找到hosts文件,添加内容即可。

hosts文件.png

以上便是我对TCP/IP协议的理解,如果不当之处还望指出。
参考:《TCP/IP详解 卷1:协议》
TCP/IP基础概述
IP,TCP 和 HTTP

上一篇 下一篇

猜你喜欢

热点阅读