裸泳的猪

沾沾自喜其实最可悲

0%

基础知识TCP

 

什么是 TCP ?

Transmission Control Protocol(传输控制协议)

TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。

  • 面向连接:一定是「一对一」才能连接,不能像 UDP 协议 可以一个主机同时向多个主机发送消息,也就是一对多是无法做到的;

  • 可靠的:无论的网络链路中出现了怎样的链路变化,TCP 都可以保证一个报文一定能够到达接收端;

  • 字节流:消息是「没有边界」的,所以无论我们消息有多大都可以进行传输。并且消息是「有序的」,当「前一个」消息没有收到的时候,即使它先收到了后面的字节已经收到,那么也不能扔给应用层去处理,同时对「重复」的报文会自动丢弃。

什么是 TCP 连接?

TCP连接主要包括三个部分:socket,序列号,窗口大小。

通过TCP连接可以控制流量,和提高可靠性。

  • Socket:由 IP 地址和端口号组成
  • 序列号:用来解决乱序问题等
  • 窗口大小:用来做流量控制

TCP

如何唯一确定一个 TCP 连接呢?

  • 源地址
  • 源端口
  • 目的地址
  • 目的端口

    有一个 IP 的服务器监听了一个端口,它的 TCP 的最大连接数是多少?

    主要受限于服务器的资源,第一是文件描述符限制,TCP连接中得socket是文件得,所以受文件描述符限制,这个由系统参数ulimit 配置,但这个也受限于系统内存,内存不大,参数设置得过大也无法实现。

UDP 和 TCP 有什么区别呢?分别的应用场景是?

UDP 是不需要连接,即刻传输数据。且可以一对多,多对多。UDP 是尽最大努力交付,不保证可靠交付数据。UDP没有流量控制。UDP首部只有 8 个字节,并且是固定不变的,开销较小

TCP则是面向连接的,只能一对一,TCP比较可靠数据可以无差错、不丢失、不重复、按需到达,可以进行流量控制。

一句话来说UDP比较高效,舍弃了可靠性,TCP则是专注于点对点的高质量传输。

TCP:

FTP 文件传输

HTTP / HTTPS


UDP

由于 UDP 面向无连接,它可以随时发送数据,再加上UDP本身的处理既简单又高效,因此经常用于:

包总量较少的通信,如 DNS 、SNMP 等

视频、音频等多媒体通信

广播通信

为什么 UDP 头部没有「首部长度」字段,而 TCP 头部有「首部长度」字段呢?

原因是 TCP 有可变长的「选项」字段,而 UDP 头部长度则是不会变化的,无需多一个字段去记录 UDP 的首部长度。

三次握手,四次挥手

三次握手

  1. 一开始,客户端和服务端都处于 CLOSED 状态。先是服务端主动监听某个端口,处于 LISTEN 状态;
  2. 客户端发起一个SYN请求,同时送过去随机生成的客户端序列号client_isn,之后客户端处于 SYN-SENT 状态。
  3. 服务端接收到SYN请求,返回一个ACK和服务端的SYN,其次把 TCP 首部的「确认应答号」字段填入 client_isn + 1,生成一个服务端的序列号server_isn,传送给客户端,之后服务端处于 SYN-RCVD 状态;
  4. 客户端收到服务端报文后,还要向服务端回应最后一个应答报文,首先该应答报文 TCP 首部 ACK 标志位置为 1 ,其次「确认应答号」字段填入 server_isn + 1 ,最后把报文发送给服务端,这次报文可以携带客户到服务器的数据,之后客户端处于 ESTABLISHED 状态。
  5. 服务器收到客户端的应答报文后,也进入 ESTABLISHED 状态。

三次握手的意义

阻止历史重复连接的初始化(主要原因)

三次握手才可以同步双方的初始序列号

三次握手才可以避免资源浪费

从上面的过程可以发现第三次握手是可以携带数据的,前两次握手是不可以携带数据的。

如何在 Linux 系统中查看 TCP 状态?

TCP 的连接状态查看,在 Linux 可以通过 netstat -napt 命令查看。

四次挥手

  1. 客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入 FIN_WAIT_1 状态。
  2. 服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSED_WAIT 状态。
  3. 客户端收到服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态。
  4. 等待服务端处理完数据后,也向客户端发送 FIN 报文,之后服务端进入 LAST_ACK 状态。
  5. 客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态
  6. 服务器收到了 ACK 应答报文后,就进入了 CLOSE 状态,至此服务端已经完成连接的关闭。
  7. 客户端在经过 2MSL 一段时间后,自动进入 CLOSE 状态,至此客户端也完成连接的关闭。

主动关闭连接的,才有 TIME_WAIT 状态。

TCP性能的优化

tcp_syn_retries 控制SYN包重传的次数,默认值是5

1
echo 5 > /proc/sys/net/ipv4/tcp_syn_retries

如何查看由于 SYN 半连接队列已满,而被丢弃连接的情况?

1
netstat -s |grep "SYNs to LISTEN"

 上面输出的数值是累计值,表示共有多少个 TCP
连接因为半连接队列溢出而被丢弃。隔几秒执行几次,如果有上升的趋势,说明当前存在半连接队列溢出的现象。

如何查看由于 accept 连接队列已满,而被丢弃的连接?

1
date;netstat -s |grep overflowed
-------------本文结束感谢您的阅读-------------