# Linux网络编程

# OSI模型

ISO(International Organization for Standardization)即国际标准化组织为计算机的通信开发系统互连设计的模型,即OSI模型,全称计算机通信开发系统互联模型(open systems interconnection)。

该模型采用分层方式进行架构,架构如下:

# OSI网络架构

1654069971926

# OSI层次介绍

层级 名称 描述
1 物理层 进行网络链接的硬件
2 数据链路层 转发网络请求的硬件
3 网络层 IPv4&IPv6协议处理进行路由和寻址,决定数据的游走路径
4 传输层 TCP/UDP 确定两个主机间进程通信的网络传输服务
5 会话层 进行主机进程间的通信的会话管理
6 表示层 数据处理层(编码、解码、压缩、解压)
7 应用层 为计算机用户提供服务

# 套接字为什么只提供了上三层进入传输层的接口

  1. 顶上三层处理具体的网络应用(FTP,HTTP)的所有细节,对通信细节了解很少,底下四层对具体网络应用了解很少,在处理通信的细节。
  2. 因为Linux系统分为用户空间和内核空间,内核空间通常已经封装了下四层的操作,而对于大多数的应用程序,均是通过用户进程实现,因此API被构建在了传输层和会话层。

# 发现网络拓扑

netstat -i 提供网络接口的信息

Kernel Interface table
// 
Iface             MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg

docker0          1500        0      0      0 0             3      0      0      0 BMU
// 以太网接口
eth0             1500 272441368      0 143712 0      28478500      0      0      0 BMRU
// 环回接口
lo              65536 5281851012      0      0 0      5281851012      0      0      0 LRU

netstat -r 展示路由表

Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface

default         gateway         0.0.0.0         UG        0 0          0 eth0
10.14.2.0       0.0.0.0         255.255.255.0   U         0 0          0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U         0 0          0 docker0

ifconfig+网络接口名称 获取接口详细信息

ifconfig eth0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.14.2.214  netmask 255.255.255.0  broadcast 10.14.2.255
        inet6 fe80::2a6e:d4ff:fe8a:2eda  prefixlen 64  scopeid 0x20<link>
        ether 28:6e:d4:8a:2e:da  txqueuelen 1000  (Ethernet)
        RX packets 272451869  bytes 168057163491 (156.5 GiB)
        RX errors 0  dropped 143727  overruns 0  frame 0
        TX packets 28478593  bytes 16473596749 (15.3 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ping 查看本地网络中IP地址的命令

# 传输层有哪些协议?

传输层包括TCP、UDP、SCTP协议。其中,TCP和UDP是常见的,用途广泛的协议,但是SCTP是一个比较新的协议,这些网络传输协议都通过网络层IP协议进行转发。

  • UDP协议
    • 是简单的不可靠的数据报协议
  • TCP协议
    • 复杂的可靠的字节流协议
  • SCTP协议
    • SCTP协议与TCP协议相似,是一个可靠的传输协议,并且提供消息边界

# TCP/IP协议族

# 关于协议族

  • 协议是指网络通信过程中的约定或协议,通信的双方必须遵守一样的协议才能建立连接。

  • TCP/IP 模型包含了 TCP、IP、UDP、Telnet、FTP、SMTP 等上百个互为关联的协议,其中 TCP 和 IP 是最常用的两种底层协议,所以把它们统称为“TCP/IP 协议族”。

# 协议族架构图

1654072807990

# 各协议作用

协议 协议名称 协议作用
IPv4 网际协议4版本 使用32位地址,为TCP UDP SCTP ICMP IGMP提供分组递送服务
IPv6 网际协议6版本 使用128位地址 为 TCP UDP SCTP ICMPv6提供分组递送服务
TCP 传输控制协议 TCP是一个面向链接的协议,为用户进程提供可靠的全双工字节流
UDP 用户数据报协议 UDP是无连接协议,不能保证最终到达它们的目的地
SCTP 流控制传输协议 提供可靠的全双工关联的面向连接的协议
ICMP 网际控制消息协议 处理在路由器和主机之间流通的错误和控制消息
IGMP 网际组管理协议 用于多播
ARP 地址解析协议 把一个IPv4地址映射为硬件地址
RARP 反向地址解析协议 把硬件地址映射为IPv4
BPE BSD分组过滤 提供对数据链路层的访问能力

# 关于UDP协议

  • 属于传输层协议
  • 用户进程使用UDP套接字写入一个消息,该消息随后被封装到一个UDP数据报,进而被封装到一个IP数据报
  • UDP 不保证数据报送到的目的地,也不保证数据报的先后顺序
  • UDP提供无连接的服务,因为UDP和服务器之间没有长期存在的关系

# 关于TCP协议

  • TCP提供了可靠的连接和数据发送服务
  • 其首先与某个服务器建立连接,再跨连接与服务器交换数据,最后终止该连接
  • TCP并不能提供可靠的端对端的数据传输服务,但是内部建立了一套可靠的数据传递机制
  • TCP协议传输数据是有序的、基于字节流的,这是因为它为每个数据报提供了一个顺序位
  • TCP通过通告窗口实现流量控制,以实现通信的可靠性
  • TCP是双全工模式,即能够同时进行信号数据的双向传输

# 关于SCTP协议

  • SCTP协议在客户端和服务端之间提供关联关系,并像TCP那样为应用进程提供可靠性、排序、流量控制及双全工的数据传送
  • SCTP是面向消息的传送,它提供各个记录的按序递送服务
  • 能够在建立的端点间提供多个流,每个流各自可靠的按序递送消息,消息消失不会阻塞其它消息的投递

# TCP三次握手创建连接

我们在建立TCP的连接时,必须做好以下准备

  • 服务器必须准备好接受外来的连接,即能够被动打开
  • 客户通过调用connect发起主动打开,客户机将发送一个SYN分节连接中发送的数据的初始序列号
  • 服务器必须确认客户机的消息即SYN分节,本身将会发送ACK确认信号,同时发送一个SYN,将返回初始序列号
  • 客户机再次确认服务器SYN

1654075001924

# TCP 协议选项

TCP选项中的参数及含有

1654075158460

# MSS最大段大小选项

最大段大小是指TCP协议所允许的从对方接收到的最大报文段,最大段大小只记录TCP数据的字节数而不包括其他相关的TCP与IP头部。当建立一条TCP连接时, 通信的每一方都要在SYN报文段的MSS选项中说明自已允许的最大段大小。

# SACK选择确认选项

TCP “选择确认”(SACK)能在报文段丢失或被接收方遗漏时更好地进行重传工作。通过接收SYN (或者SYN+ACK)报文段中的“允许选择确认”选项, TCP通信方会了解到自身具有了发布SACK信息的能力。当接收到乱序的数据时, 它就能提供一个SACK选项来描述这些乱序的数据, 从而帮助对方有效地进行重传。

# WSOPT窗口缩放选项

窗口缩放选项(表示为WSCALE或WSOPT)能够有效地将TCP窗口广告字段的范围从16位增加至30位。TCP头部不需要改变窗口广告字段的大小, 仍然维持16位的数值。

# UTO用户超时选项

用户超时(UTO)选项是一个相对较新的TCP的功能。用户超时数值(也被称为USER_TIMEOUT)指明了TCP发送者在确认对方未能成功接收数据之前愿意等待该数据ACK确认的时间。

# 认证选项

TCP设置了一个选项用于增强连接的安全性,当发送数据时, TCP会根据共享的密钥生成一个通信密钥, 并根据一个特殊的加密算法计算散列值。接收者装配有相同的密钥, 同样也能够生成通信密钥

(63条消息) TCP的连接与断开_zkccpro的博客-CSDN博客_tcp连接断开 (opens new window)

# TCP四次挥手终止连接

  • 应用进程首先调用close,执行主动关闭,TCP发送一个FIN分节,表示数据发送完毕
  • 接收到FIN的对端执行被动关闭,这个FIN由TCP确认,它的接收也作为一个文件结束符传递给接收端应用程序
  • 接收该文件结束符的应用将调用close关闭套接字,并发送FIN
  • 接收这个最终FIN的原发送端TCP确认这个FIN

1654079255729

# TCP 状态转换图

1654130489526

# 什么是端口号

端口号的主要作用是表示一台计算机中的特定进程所提供的服务。网络中的计算机是通过IP地址来代表其身份的,它只能表示某台特定的计算机,但是一台计算机上可以同时提供很多个服务,如数据库服务、FTP服务、Web服务等,我们就通过端口号来区别相同计算机所提供的这些不同的服务,如常见的端口号21表示的是FTP服务,端口号23表示的是Telnet服务端口号25指的是SMTP服务等。

  • TCP/UDP是16位字节的端口,因此端口号16位整数
  • 端口号小于256定义为常用端口,服务器一般通过常用端口识别
  • 端口号只需保证端口号在本机唯一就可以了
  • 客户端端口号因为存在时间太短被称为临时端口
  • 大多数TCP/IP分配了1024-49151之间的端口,即用户端口
  • 私用端口是49152-65535
  • 任何TCP/IP实现的提供服务都用1-1023之间的端口

1654131805283

如图,为LANA和BSD规范的不同的端口使用,目前以LANA为主

# 什么是套接字

# 套接字

标识每个端点的两个值(IP和端口号)通常称为一个套接字。

# 套接字对

套接字对,则标识为连接两个端点的四元组:本地IP地址、本地TCP端口号、外地IP地址、外地TCP端口号。

# 套接字的记号

{*:21,*:*}

* 是通配符,用来指定本地IP的地址

: 用来将IP地址和端口号进行连接,即某个IP的某个端口连接服务器

# 并发服务器如何处理请求

并发服务器中主服务器循环通过派生一个子进程来处理每个新的连接。

并发服务器在处理客户连接时,fork一个自身的副本,让子进程来处理客户的请求。

1654132754166

# 套接字缓冲区及限制

# MTU 最大传输单元

  • 最大传输单元,在数据链路层 (opens new window)中,往往规定了MTU大小
  • IP层的数据包通过数据链路层如果大于MTU,将被分片,到达接收端IP层后再被重组
  • 以太网的MTU为1500字节

# MSS 最大报文段

  • 最大报文段,是TCP协议的一个选项。
  • MSS选项用于在TCP建立连接时,收发双方协商一个TCP报文段所能承载的最大数据长度。
  • MSS选项只在初始化连接请求(SYN=1)的报文段中使用。
  • 选择合适的MSS很重要。如果MSS小了,网络利用率低。如果MSS大了,由于在网络层需要分片,也会影响网络性能。
  • 一般MSS的长度为MTU(1500)-IP首部(20)-TCP首部(20)=1460字节。

# TCP 缓冲区及数据输出

1654134895613

  1. 应用程序调用write函数将数据写入内核缓冲区
  2. 内核从缓冲区中将数据复制到套接字的发送缓冲区
    1. 发送缓冲区无法容纳应用程序的数据时,应用程序进入睡眠
    2. TCP中提供了 SO_SNDBUF套接字更改缓冲区大小
  3. TCP在进行数据发送时,往往在本地留有副本,直到确认对端收到副本为止
  4. 本端TCP以MSS大小或更小的字节块将数据传递给IP,同时每个字节块被做了标记
  5. IP为每个块新增IP标记,构成IP数据报,根据目标IP地址查找路由表选项以确定外出接口,然后数据被传递给相应的数据链路

# UDP缓冲区及数据输出

1654135121893

  • UDP因为并不可靠,因此并没有缓冲区进行数据的留存和观察