ethermet socket
TCP/UDP
TCP保证可靠性
- 序列号、确认应答、超时重传
- 数据到达接收方,接收方需要发出一个确认应答,表示已经收到该数据段,并且确认序号会说明它下一次需要接收的数据序列号。如果发送方迟迟未收到确认应答,那么可能是发送的数据丢失,也可能是确认应答丢失,这时发送方在等待一定时间后会进行重传。这个时间一般是2*RTT(报文段往返时间)+一个偏差值
- 窗口控制与高速重发控制/快速重传(重复确认应答)
- TCP会利用窗口控制来提高传输速度,意思是在一个窗口大小内,不用一定要等到应答才能发送下一段数据,窗口大小就是无需等待确认而可以继续发送数据的最大值。如果不使用窗口控制,每一个没收到确认应答的数据都要重发。使用窗口控制,如果数据段1001-2000丢失,后面数据每次传输,确认应答都会不停地发送序号为1001的应答,表示我要接收1001开始的数据,发送端如果收到3次相同应答,就会立刻进行重发;但还有种情况有可能是数据都收到了,但是有的应答丢失了,这种情况不会进行重发,因为发送端知道,如果是数据段丢失,接收端不会放过它的,会疯狂向它提醒…
TCP 三次握手建立连接(Three-way Handshake)
TCP 连接的建立需要经过三次握手,确保客户端和服务器双方都具备发送和接收数据的能力。过程如下:
第一次握手:客户端发送 SYN
- 客户端向服务器发送一个带 SYN 标志位的数据包(SYN=1,Seq=x),表示请求建立连接。
- 此时客户端进入 SYN_SEND 状态。
第二次握手:服务器应答 SYN+ACK
- 服务器收到 SYN 包后,确认客户端的 SYN(ACK=1,Ack=x+1),同时自己也发送一个 SYN 包(SYN=1,Seq=y)。
- 服务器将 SYN 和 ACK 一起发送(SYN=1,ACK=1,Seq=y,Ack=x+1)。
- 服务器进入 SYN_RCVD 状态。
第三次握手:客户端确认 ACK
- 客户端收到服务器的 SYN+ACK 包后,发送一个确认包(ACK=1,Seq=x+1,Ack=y+1)给服务器。
- 客户端进入 ESTABLISHED 状态,服务器收到后也进入 ESTABLISHED 状态,连接建立完成。
说明
- 三次握手的目的是同步双方的初始序列号(Seq),并确认双方的接收能力。
- 若握手过程中某一步失败,连接不会建立,需重新发起。
- 握手完成后,双方可以开始可靠的数据传输。
TCP 四次挥手断开连接(Four-way Handshake)
TCP 连接的断开需要经过四次挥手,确保双方都能完成数据传输并正常释放资源。过程如下:
第一次挥手:客户端发送 FIN
- 客户端向服务器发送一个带 FIN 标志位的数据包(FIN=1,Seq=u),表示客户端没有数据要发送了,请求关闭连接。
- 客户端进入 FIN_WAIT_1 状态。
第二次挥手:服务器应答 ACK
- 服务器收到 FIN 包后,发送一个确认包(ACK=1,Ack=u+1,Seq=v)给客户端,表示已收到关闭请求。
- 服务器进入 CLOSE_WAIT 状态,客户端收到 ACK 后进入 FIN_WAIT_2 状态。
第三次挥手:服务器发送 FIN
- 服务器处理完剩余数据后,向客户端发送一个带 FIN 标志位的数据包(FIN=1,Seq=w),请求关闭连接。
- 服务器进入 LAST_ACK 状态。
第四次挥手:客户端应答 ACK
- 客户端收到服务器的 FIN 包后,发送一个确认包(ACK=1,Ack=w+1)给服务器。
- 客户端进入 TIME_WAIT 状态,等待一段时间后彻底关闭连接;服务器收到 ACK 后立即关闭连接,进入 CLOSED 状态。

tcp三次握手和四次挥手的原因
为什么是三次握手?
- 为了防止已失效的连接请求报文段突然有送到了B,因而产生错误
- 假设两次握手时,A发出的第一个请求连接报文段在某一网络节点长时间滞留,以致延误到连接释放后才到达B。B收到失效的连接请求报文段后,认为是A又发出一次新的连接请求。于是向A发送确认报文段,同意建立连接,此时在假定两次握手的前提下,连接建立成功。这样会导致B的资源白白浪费
- 假设两次握手时,A发出一个请求报文段,但发送过后A就因为问题而导致下线。之后B收到了A发来的请求连接报文段,给A发送确认报文段,同意建立连接,此时在假定两次握手的前提下,连接建立成功。这样会导致B的资源白白浪费
为什么是四次挥手?
- TCP协议是全双工通信,这意味着客户端和服务器端都可以向彼此发送数据,所以关闭连接是双方都需要确认的共同行为
- 假设是三次挥手时,首先释放了A到B方向的连接,此时TCP连接处于半关闭(Half-Close)状态,这时A不能向B发送数据,而B还是可以向A发送数据。如果此时A收到了B的确认报文段后,就立即发送一个确认报文段,这会导致B向A还在发送数据时连接就被关闭。这样会导致A没有完整收到B所发的报文段
TCP状态变迁(状态机)

time_wait
首先调用close()发起主动关闭的一方,在发送最后一个ACK之后会进入time_wait的状态,也就说该发送方会保持2MSL时间之后才会回到初始状态。MSL指的是数据包在网络中的最大生存时间。产生这种结果使得这个TCP连接在2MSL连接等待期间,定义这个连接的四元组(客户端IP地址和端口,服务端IP地址和端口号)不能被使用。
- 为实现TCP全双工连接的可靠释放
由TCP状态变迁图可知,假设发起主动关闭的一方(client)最后发送的ACK在网络中丢失,由于TCP协议的重传机制,执行被动关闭的一方(server)将会重发其FIN,在该FIN到达client之前,client必须维护这条连接状态,也就说这条TCP连接所对应的资源(client方的local_ip,local_port)不能被立即释放或重新分配,直到另一方重发的FIN达到之后,client重发ACK后,经过2MSL时间周期没有再收到另一方的FIN之后,该TCP连接才能恢复初始的CLOSED状态。如果主动关闭一方不维护这样一个TIME_WAIT状态,那么当被动关闭一方重发的FIN到达时,主动关闭一方的TCP传输层会用RST包响应对方,这会被对方认为是有错误发生,然而这事实上只是正常的关闭连接过程,并非异常。 - 为使旧的数据包在网络因过期而消失
先假设TCP协议中不存在TIME_WAIT状态的限制,再假设当前有一条TCP连接:(local_ip, local_port, remote_ip,remote_port),因某些原因,我们先关闭,接着很快以相同的四元组建立一条新连接。TCP连接由四元组唯一标识,因此,在我们假设的情况中,TCP协议栈是无法区分前后两条TCP连接的不同的,在它看来,这根本就是同一条连接,中间先释放再建立的过程对其来说是“感知”不到的。这样就可能发生这样的情况:前一条TCP连接由local peer发送的数据到达remote peer后,会被该remot peer的TCP传输层当做当前TCP连接的正常数据接收并向上传递至应用层(而事实上,在假设的场景下,这些旧数据到达remote peer前,旧连接已断开且一条由相同四元组构成的新TCP连接已建立,因此,这些旧数据是不应该被向上传递至应用层的),从而引起数据错乱进而导致各种无法预知的诡异现象。作为一种可靠的传输协议,TCP必须在协议层面考虑并避免这种情况的发生,这正是TIME_WAIT状态存在的第2个原因。
具体而言,local peer主动调用close后,此时的TCP连接进入TIME_WAIT状态,处于该状态下的TCP连接不能立即以同样的四元组建立新连接,即发起active close的那方占用的local port在TIME_WAIT期间不能再被重新分配。由于 TIME_WAIT状态持续时间为2MSL,这样保证了旧TCP连接双工链路中的旧数据包均因过期(超过MSL)而消失,此后,就可以用相同的四元组建立一条新连接而不会发生前后两次连接数据错乱的情况。
TCP 与 UDP 的区别
| 特性 | TCP(传输控制协议) | UDP(用户数据报协议) |
|---|---|---|
| 连接方式 | 面向连接(三次握手) | 无连接 |
| 可靠性 | 可靠,保证数据顺序和完整性 | 不可靠,可能丢包、乱序 |
| 传输方式 | 字节流,面向流 | 数据报,面向报文 |
| 流量控制 | 有(滑动窗口、拥塞控制等) | 无 |
| 速度 | 较慢(因需保证可靠性) | 较快 |
| 适用场景 | 文件传输、网页、邮件等 | 视频、语音、DNS、广播等 |
| 首部开销 | 20字节(不含选项) | 8字节 |
| 是否有顺序保证 | 有 | 无 |
| 是否有重传机制 | 有 | 无 |
TCP拥塞控制
慢启动
设置慢启动阈值,一般开始都设为65536。拥塞避免是指当拥塞窗口大小达到这个阈值,拥塞窗口的值不再指数上升,而是加法增加(每次确认应答/每个rtt,拥塞窗口大小+1),以此来避免拥塞。将报文段的超时重传看做拥塞,则一旦发生超时重传,我们需要先将阈值设为当前窗口大小的一半,并且将窗口大小设为初值1,然后重新进入慢启动过程。
快速重传
在遇到3次重复确认应答(高速重发控制)时,代表收到了3个报文段,但是这之前的1个段丢失了,便对它进行立即重传。然后,先将阈值设为当前窗口大小的一半,然后将拥塞窗口大小设为慢启动阈值+3的大小。这样可以达到:在TCP通信时,网络吞吐量呈现逐渐的上升,并且随着拥堵来降低吞吐量,再进入慢慢上升的过程,网络不会轻易的发生瘫痪。
OSI参考模型
| OSI模型层级 | Linux TCP/IP模型 | 常用协议示例 | 典型网络设备/功能 |
|---|---|---|---|
| 7. 应用层 | 应用层 | HTTP, FTP, SSH, DNS, SMTP | 网页服务器、邮件服务器 |
| 6. 表示层 | TLS, SSL, JPEG, GIF | 加密/解密、编码/解码 | |
| 5. 会话层 | RPC, NetBIOS, SMB | 会话管理 | |
| 4. 传输层 | 传输层 | TCP, UDP | 路由器、交换机(L4功能) |
| 3. 网络层 | 网络层 | IP, ICMP, ARP, IGMP | 路由器 |
| 2. 数据链路层 | 链路层 | Ethernet, PPP, VLAN, MAC | 交换机、网卡 |
| 1. 物理层 | 物理层 | RJ45, 光纤, 电缆, 无线信号 | 集线器、网线、无线模块 |
TCP/IP数据链路层的交互
网络层等在数据链路层用MAC地址作为通信目标,数据包到达网络层等往数据链路层发送的时候,首先会去ARP缓存表去查找ip对应的MAC地址,如果查到了,就将此ip对应的MAC地址封装到链路层数据包的包头。如果缓存中没有找到,则会发起一个广播,who is ip xxx tell ip xxxx,所有收到广播的机器看到这个ip是不是自己的,如果是自己的,则以单播的形式将自己的mac地址回复给请求机器。
浏览器堆URL的解析
浏览器要将URL解析为IP地址,解析域名就要用到DNS协议,首先主机会查询DNS的缓存,如果没有就给本地DNS发送查询请求。DNS查询分为两种方式,一种是递归查询,一种是迭代查询。如果是迭代查询,本地的DNS服务器,向根域名服务器发送查询请求,根域名服务器告知该域名的一级域名服务器,然后本地服务器给该一级域名服务器发送查询请求,然后依次类推直到查询到该域名的IP地址。DNS服务器是基于UDP的,因此会用到UDP协议。得到IP地址后,浏览器就要与服务器建立一个http连接。因此要用到http协议。http生成一个get请求报文,将该报文传给TCP层处理,所以还会用到TCP协议。如果采用https还会使用https协议先对http数据进行加密。TCP层如果有需要先将HTTP数据包分片,分片依据路径MTU和MSS。TCP的数据包然 后会发送给IP层,用到IP协议。IP层通过路由选路,一跳一跳发送到目的地址。当然在一个网段内的寻址是通过以太网协议实现(也可以是其他物理层协议,比如PPP, SLIP),以太网协议需要直到目的IP地址的物理地址,又需要ARP协议。
其中:
- DNS协议,http协议,https协议属于应用层
- TCP/UDP属于传输层
- 传输层的任务就是负责主机中两个进程之间的通信。因特网的传输层可使用两种不同协议:即面向连接的传输控制协议TCP,和无连接的用户数据报协议UDP。面向连接的服务能够提供可靠的交付,但无连接服务则不保证提供可靠的交付,它只是“尽最大努力交付”。这两种服务方式都很有用,备有其优缺点。在分组交换网内的各个交换结点机都没有传输层。
- IP协议,ARP协议属于网络层
- 网络层负责为分组交换网上的不同主机提供通信。在发送数据时,网络层将运输层产生的报文段或用户数据报封装成分组或包进行传送。在TCP/IP体系中,分组也叫作IP数据报,或简称为数据报。网络层的另一个任务就是要选择合适的路由,使源主机运输层所传下来的分组能够交付到目的主机。
- 数据链路层
- 当发送数据时,数据链路层的任务是将在网络层交下来的IP数据报组装成帧,在两个相邻结点间的链路上传送以帧为单位的数据。每一帧包括数据和必要的控制信息(如同步信息、地址信息、差错控制、以及流量控制信息等)。控制信息使接收端能够知道一个帧从哪个比特开始和到哪个比特结束。控制信息还使接收端能够检测到所收到的帧中有无差错
- 物理层
- 物理层的任务就是透明地传送比特流。在物理层上所传数据的单位是比特。传递信息所利用的一些物理媒体,如双绞线、同轴电缆、光缆等,并不在物理层之内而是在物理层的下面。因此也有人把物理媒体当做第0层。
HTTP/IP
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web)服务器传输超文本到本地浏览器的传送协议。
HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件,图片文件,查询结果等)。
特点
- 简单快速
- 客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
- 灵活
- HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
- 无连接
- 无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
- 无状态
- HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
- 支持B/S及C/S模式。
- 默认端口80
- 基于TCP协议

