ICS11 网络编程
type
status
date
slug
summary
tags
category
icon
password
计算机网络 Computer Networking
计算机网络是现代信息技术的基础,它连接了全球数十亿的设备,实现了信息的快速、高效传输。本节将梳理计算机网络的核心概念、协议和技术,从互联网的构成到网络安全,再到网络编程。
因特网 Internet
因特网由多种要素构成,包括实体、服务、协议和标准。其中:
- Host(主机):接入网络的终端设备。
- Packet Switch(分组交换机):负责收发数据包的交换机,如路由器。
- Communication Links(通信链路):通信信道,如光纤、导线、无线电。
- Networks(网络):实体、设备和信道的集合。
- Protocol(协议):规范信息收发的规则,如HTTP、HTTPS、Skype、TCP、IP、WiFi。
- Infrastructure(基础设施):支持网络运行的底层服务。
网络协议是互联网通信的基石,它规范了网络上的所有通信行为。协议定义了传输的格式、信息的次序以及发送和接收信息时应采取的行动。例如,TCP 协议的通信过程通常包括请求连接、响应连接、发送指令和传输文件等步骤。
网络的端设备(Network Edge)主要由主机(hosts)构成,包括用户端和服务器。与之对应的是网络核心(Network Core),由互联的路由器等核心设备组成,负责数据包的路由和转发。
在计算机网络发展的早期,人们使用Digital Subscriber Line(数字用户线路)接入网络,这是一种基于电话线(铜质双绞线)的通信,使用 DSL Modem(调制解调器)进行编码解码。
之后,发展出了Cable-based Access(有线电视网络接入),基于有线电视网络中的混合光纤同轴电缆(HFC),使用 Cable Modem进行信号的编解码。
WLAN 也即 Wireless Local Area Network,无线局域网。使用 IEEE 802.11 标准的无线网络通常称为 Wi-Fi(Wireless Fidelity)。
网络的物理媒介
物理媒介是信息在网络中传播的载体,不同的媒介具有不同的特性:
- 同轴电缆:支持双向传输,速率可达 100Mbps。
- 光纤:提供 10-100Gbps 的高速率,具有低错误率和强抗干扰能力,对电磁噪声的抵抗性好。
- 无线电:通过调制到电磁波进行传输,频率影响传输速率和衍射能力。无线电传输包括WLAN(无线局域网)、广域网(4G/5G)、蓝牙、微波、卫星通信。
网络安全
网络安全是保障网络正常运行和保护用户数据的重要环节。常见的网络安全威胁包括病毒、蠕虫、木马、间谍软件以及分布式拒绝服务(DDoS)攻击。恶意软件通常具有自我复制的能力。攻击手段包括信息嗅探(packet sniffing)和 IP 地址欺骗(IP spoofing)。
拒绝服务(DoS)攻击通过超量访问服务器等资源,发送大量请求以遮蔽正常请求,从而导致服务不可用。
防御措施包括:
- 身份验证:要求通信对方证明身份。
- 加密:使用公钥和私钥对数据进行加密,保护数据隐私。
- 防火墙:设置防火墙,过滤恶意流量。
OSI 协议栈
OSI(Open Systems Interconnection,开放系统互连)模型是一个概念模型,用于描述网络协议的层次结构。每一协议层都代表一种特定的服务。
1. 物理层(Physical Layer)
- 功能:处理物理连接和传输介质,如电缆、光纤、无线电波等。定义了电气、机械和功能特性,以激活、维护和停用物理连接。
- 协议示例:Ethernet(以太网)、RS-232、USB、Wi-Fi(802.11)。
2. 链路层(Data Link Layer)
- 功能:在物理层之上,负责在直接相连的节点之间传输数据帧,并进行错误检测和纠正。它还管理物理地址(MAC 地址)。每个硬件网口唯一对应一个 MAC 地址,因此可以用作进网许可标识号。链路层关注相邻结点之间的单次传输。
- 协议示例:Ethernet、Wi-Fi(802.11)、PPP(点对点协议)、HDLC(高级数据链路控制)。
3. 网络层(Network Layer)
- 功能:负责数据包的路由和转发,确保数据包能够从源地址传输到目标地址。它处理逻辑地址(如 IP 地址)和路由选择。网络层关注传输的途径点。
- 协议示例:IP(Internet Protocol)、ICMP(Internet Control Message Protocol)、OSPF(开放最短路径优先)、BGP(边界网关协议)。
4. 传输层(Transport Layer)
- 功能:提供端到端的通信服务,确保数据传输的可靠性和完整性。它处理数据的分段、重组、流量控制和错误恢复。传输层关注传输的起点和终点。
- 协议示例:TCP(传输控制协议)、UDP(用户数据报协议)。
5. 应用层(Application Layer)
- 功能:直接与用户交互,提供网络服务和应用程序接口。它处理用户请求并提供相应的服务。
- 协议示例:HTTP(超文本传输协议)、FTP(文件传输协议)、SMTP(简单邮件传输协议)、DNS(域名系统)。
交换机通常运行在链路层和物理层,而路由器则运行在网络层、链路层和物理层。
无线网络(仅了解)
无线网络具有两个主要特征:无线(wireless):通过无线电组成网络。移动(mobility):主机位置可以变动。
无线网络的组成部分包括:
- 网络基础设施,通常是有线的。
- 基站(base station),与有线网络连接,提供无线连接,例如信号塔。
- 802.11 规定的接入点(access point,AP)。
不同无线技术的速率比较:
- 蓝牙:2Mbps
- 802.11b/g:11-54Mbps
- 4G LTE/802.11n:~600Mbps
- 5G:~10Gbps
无线网络有两种主要模式:
- 基础设施模式:无线设备先连接到基站,通过基站接入有线网络。无线设备位置移动时在不同基站间切换。
- 无基础设施/自组织模式:没有基站,无线设备只能与通信范围内的其他设备通信。所有设备进行自组织,可以充当通信链路上的路由器(转发数据)。
WiFi 采用基础设施模式,主机通过单跳接入基站;蓝牙采用自组织模式,单跳接入主设备。
网络编程
网络编程是现代计算机科学中的一个重要领域,涉及如何在不同计算机之间进行数据传输和通信。理解网络协议、客户端-服务器模型、数据传输机制以及套接字编程是掌握网络编程的基础。
网络协议
- 规定了命名机制:主机/路由器的地址格式
- 规定了传输机制:标准传输单位为包(packet),包括包头(header)和负载(payload)。包头包含包大小、发信人和收信人的地址。
数据通过封装(Encapsulation)传递
OSI中每一层实际上都在对原始数据进行封装:
- 应用层产生需要传递的数据,称为报文(message)
- 传输层(TCP等)将数据分割成较小的数据报(datagram),增加传输层头,记录源端口和目的端口
- 网络层(IP等)将数据封装成包(packet),增加网络层头/包头(IP头),记录源IP和目的IP
- 链路层将数据封装成帧(frame),增加链路层头/帧头(以太网头),记录源MAC地址和目的MAC地址
- 物理层通过信道进行比特流传输
数据通过路由器(router)在局域网(LAN)间传递时,路由器通过LAN1适配器接收帧,通过协议软件处理LAN帧头,按需求更换帧头,并通过LAN2适配器发出帧。

基于TCP/IP的互联网
在网络层,IP协议提供端到端(host2host)的基础命名方式(IP地址),规定包的通信容量。
IP地址是所有网络设备的唯一标识符,IPv4使用32bit标识,分为四个8bit字段(0-255)方便记忆,范围为
0.0.0.0-255.255.255.255
。其中 127.0.0.0
用于标识本主机。IPv6使用128bit标识,分为8组4位16进制数。域名解析系统(Domain Name System, DNS)将网站域名解析成IP地址,人们只需记忆网站的域名(例如 its.pku.edu.cn),由DNS维护域名到IP地址的映射。一个域名可能映射到多个IP地址,一个IP地址也可能对应于多个域名。
在传输层,主要有UDP和TCP两种协议:
UDP(User Datagram Protocol):通过IP提供进程到进程、不可靠的数据段传输。
TCP(Transmission Control Protocol):通过IP提供进程到进程、可靠的字节流传输。TCP在传输前需要建立连接(connection)。通过三次握手建立连接,四次挥手终止连接。
TCP适用于对完整性要求较高、实时性要求较低的网络连接;UDP适用于对实时性要求高、可以容许一定丢包的网络连接,例如视频通话和竞技游戏。
TCP connection
client和server在传输层通过TCP协议建立连接,进行字节流式传递。有以下特点:
- 连接是点对点的、进程到进程的
- 连接是全双工(full duplex)的,允许同一时间双向传输。
- 半双工:允许异步双向传输
- 单工(simplex):只允许单向传递
- 连接是可靠的(reliable),保序的
套接字(socket)是连接的一个端点(endpoint);socket的地址是IP地址-端口对。
端口(port)是16bit整数,标识主机的一个进程
- 分为知名(well-known)端口,占用0-1023,例如HTTP、SSH;注册(Registered)端口,占用1024-49151,例如MySQL;以及动态/私有端口。
- HTTP使用80端口,HTTPS使用443端口,ssh使用22端口。服务器主机被通过不同端口访问时,启用的服务也不同。
端口用于区分同一主机上的不同应用程序或服务。
IP地址用于在网络中唯一标识主机,并确定数据包的传输路径。
MAC地址用于在子网中唯一标识主机,并进行数据帧的传输。
套接字(socket)是IP+端口号,用于唯一标识连接的一端。
子网 subnet
现今,虽然容量更大的IPv6已投入运行,但大部分互联网设备仍使用IPv4。注意到IPv4使用4字节,最多维护
2^32
(约42亿)个IP地址,已远远不能满足现今的需求。为了解决IP地址不够用的问题,可以将一些网络设备组成一个子网。子网(Subnet)是网络中的一个逻辑划分,用于将大型网络分割成更小的、更易管理的部分。子网内的设备可以相互通信,同时也可以通过路由器与其他子网或外部网络通信。整个子网对外只使用一个IP地址(网关IP地址)。
子网掩码将IP地址划分为网络部分和主机部分。网络部分标识子网,主机部分标识子网中的设备。IPv4中,使用8/16/24 bit作为网络部分,分别称为A/B/C类网络。网络部分的高位前缀分别为0/10/110。子网掩码也即网络部分比特全为1,主机部分比特全为0的掩码。此时IP地址的格式为
x.y.z.w/n
,n表示网络部分比特数。子网内部设备之间的通信通常不需要经过路由器,而是通过交换机或直接连接完成。内部通信使用MAC地址(数据链路层)作为唯一标识符并进行通信。通常使用ARP(地址解析协议)来解析IP地址到MAC地址的映射。通信速度快,延迟低,因为数据包不需要经过路由器。
子网内的设备与子网外的设备(其他子网或互联网)之间的通信需要通过路由器(或网关)来完成。外部通信使用IP地址(网络层)进行路由。通信速度较慢,延迟较高,因为数据包需要经过路由器转发。运用NAT技术,可以让整个子网对外只表示为一个IP地址。
NAT(Network Address Translation,网络地址转换)
NAT是一种用于改变 IP 地址的技术,通常在路由器上实现。NAT 的主要功能包括:
- 地址转换:将局域网中的私有 IP 地址映射到外部(通常是公网) IP 地址。
- 会话跟踪:通过端口号区分多个内部设备的通信会话。
- 地址隐藏:局域网内的设备对外只表现为一个公共 IP 地址,隐藏内部网络的结构。
NAT 的典型应用是在路由器上,允许局域网内的多个设备通过一个公共(外部) IP 地址访问互联网。实现 NAT 下的子网间通信的方式有:
端口转发(Port Forwarding)
端口转发是最常见的方法,用于允许外部网络访问 NAT 后的内部设备。将 NAT 路由器的公共 IP 地址和特定端口号映射到内部网络的某个设备和端口。当外部设备访问 NAT 路由器的公共 IP 和指定端口时,NAT 路由器会将请求转发到内部设备。例如:
主机 A(子网 A,
192.168.1.10
)需要访问子网 B 内的主机 B(192.168.2.20
)。在子网 B 的 NAT 路由器上,配置端口转发:将公共 IP(
203.0.113.2
)的某个端口(如 8080
)映射到主机 B 的私有 IP(192.168.2.20
)和端口(如 80)。主机 A 通过访问
203.0.113.2:8080
,NAT 路由器将请求转发到主机 B。双向端口转发
如果两个子网都需要互访,可以在两个 NAT 路由器上同时设置端口转发。例如:
子网 A 的 NAT 路由器(公共 IP:
203.0.113.1
)上配置转发规则,将外部请求(如 203.0.113.1:8081
)映射到子网 A 的某台设备(如 192.168.1.10
)。子网 B 的 NAT 路由器(公共 IP:
203.0.113.2
)上也配置类似规则,将外部请求映射到子网 B 的设备。这样,双方可以通过公共 IP 和端口号互相访问。
虚拟专用网络(VPN)
VPN 是一种更为通用的解决方案,用于在两个子网之间建立一个安全的通信通道。在两个 NAT 路由器之间建立 VPN 隧道,创建一个逻辑上的专用网络。VPN 会将两个子网“桥接”到一起,使得两个子网内的设备可以直接通过私有 IP 地址互相访问。例如:
子网 A 和子网 B 的 NAT 路由器分别配置 VPN。
VPN 隧道建立后,子网 A 的设备(如
192.168.1.10
)可以直接访问子网 B 的设备(如 192.168.2.20
),反之亦然。所有通信在 VPN 隧道中加密传输,安全性更高。
私有地址 Private/Unrooted Address
私有IP地址是指在互联网上不可路由的IP地址,只能在局域网(LAN)内部使用。私有IP地址不会出现在互联网上,因此不会与其他网络冲突。子网网关(路由器)不会让目的为私有地址的传输传出子网。
私有IP地址分为三个范围:
- A类私有地址:10.0.0.0 到 10.255.255.255(/8)
- B类私有地址:172.16.0.0 到 172.31.255.255(/12)
- C类私有地址:192.168.0.0 到 192.168.255.255(/16)
域名 Domain Name
域名的阅读顺序从右往左,越靠结构越大。
顶级域名分为国家地区顶级域/通用顶级域:com(commercial)、cn、edu
二级域名为类别域/行政区域/公司名:com、net、sh、google
子域名:www、blog、mail,多用于区分网站提供的服务
IP地址和域名之间没有唯一的关系,浏览器通过DNS进行解析
客户端-服务器模型
存在一个server(服务器)进程,一个或多个client(客户端)进程。server保管一些资源(resource),通过为client分发资源来提供服务(service)。
具体而言,客户端创建一个client文件描述符;服务器创建一个监听描述符、之后等待请求。客户端向socket写入;服务器从socket读入,在本地处理后,向socket写入;客户端从socket读出数据。
Socket编程
Socket是网络通信的端点,可以看作是网络上的一个“插座”,用于数据的发送和接收。
IP地址和端口号:IP地址用于标识网络中的主机,端口号用于标识主机上的特定进程。
协议:常用的协议有TCP(传输控制协议)和UDP(用户数据报协议)。
TCP Socket编程通常分为服务器端和客户端两部分。
服务器端步骤:
- 创建Socket:使用
socket()
函数创建一个Socket。
- 绑定Socket:使用
bind()
函数将Socket与特定的IP地址和端口号绑定。
- 监听连接:使用
listen()
函数使Socket进入监听状态,等待客户端的连接请求。
- 接受连接:使用
accept()
函数接受客户端的连接请求,返回一个新的Socket用于与客户端通信。
- 收发数据:使用
recv()
和send()
函数与客户端进行数据交换。
- 关闭Socket:使用
close()
函数关闭Socket。
客户端步骤:
- 创建Socket:使用
socket()
函数创建一个Socket。
- 连接服务器:使用
connect()
函数连接到服务器的IP地址和端口号。
- 收发数据:使用
recv()
和send()
函数与服务器进行数据交换。
- 关闭Socket:使用
close()
函数关闭Socket。
服务器代码示例
客户端代码示例
socket编程相关数据类型
数据类型 | 描述 |
struct sockaddr | 通用的地址结构,所有具体的地址结构(如 sockaddr_in )都可以强制转换为它。 |
struct sockaddr_in | 用于存储 IPv4 地址信息。包含地址类型、端口号、IPv4 地址等。 |
struct sockaddr_in6 | 用于存储 IPv6 地址信息。 |
socklen_t | 表示地址结构的长度(通常是 sizeof(struct sockaddr_in) )。 |
socket编程常用函数
函数名 | 函数原型 | 参数意义 |
socket | int socket(int domain, int type, int protocol) | domain: 协议簇(如 AF_INET 表示 IPv4,AF_INET6 表示 IPv6)
type: Socket 类型(如 SOCK_STREAM 表示 TCP,SOCK_DGRAM 表示 UDP)
protocol: 通信协议(通常为 0 表示默认)。 |
bind | int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) | sockfd: Socket 描述符
addr: 指向地址结构的指针(如 sockaddr_in )
addrlen: 地址结构的大小。 |
listen | int listen(int sockfd, int backlog) | sockfd: Socket 描述符
backlog: 等待连接的队列最大长度 |
accept | int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) | sockfd: 监听 Socket 描述符
addr: 用于存放客户端地址的结构指针
addrlen: 指向地址结构大小的指针。 |
connect | int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) | sockfd: Socket 描述符
addr: 指向服务器地址结构的指针
addrlen: 地址结构的大小。 |
send | ssize_t send(int sockfd, const void *buf, size_t len, int flags) | sockfd: Socket 描述符
buf: 要发送的数据缓冲区指针
len: 发送数据的长度
flags: 发送标志(如 0 表示默认)。 |
recv | ssize_t recv(int sockfd, void *buf, size_t len, int flags) | sockfd: Socket 描述符
buf: 用于接收数据的缓冲区指针
len: 缓冲区的大小
flags: 接收标志(如 0 表示默认)。 |
close | int close(int sockfd) | sockfd: 要关闭的 Socket 描述符。 |
htonl | uint32_t htonl(uint32_t hostlong) | 将主机字节序的 32 位数转换为网络字节序。 |
ntohl | uint32_t ntohl(uint32_t netlong) | 将网络字节序的 32 位数转换为主机字节序。 |
IPv4 地址结构(struct sockaddr_in
)
IPv6 地址结构(struct sockaddr_in6
)
Prev
ICS10 系统级I/O
Next
ICS12 并发编程
Loading...