跳至内容

网络编程基础

网络编程是让不同主机上的程序通过网络互相通信的技术。理解底层的 TCP/IP 协议和 Socket 抽象层,是编写网络程序的基础。

架构模式

  • B/S(Browser/Server):客户端是浏览器,通过 HTTP/HTTPS 与服务器通信。无需安装客户端,但功能受浏览器限制。
  • C/S(Client/Server):专用客户端与服务器通信。可定制协议,功能更丰富,但需要安装客户端。

OSI 七层模型

OSI(Open Systems Interconnection)参考模型把网络通信分为七个抽象层,各层职责清晰:

层级名称协议/功能举例数据单元
7应用层HTTP、FTP、SMTP、DNS数据
6表示层加密、压缩、编码转换数据
5会话层会话建立与管理数据
4传输层TCP、UDP段(Segment)
3网络层IP、ARP、ICMP包(Packet)
2数据链路层Ethernet、MAC 地址帧(Frame)
1物理层电缆、光纤、无线信号位(Bit)
  • 发送时数据从上至下逐层封装(添加各层头部)。
  • 接收时数据从下至上逐层解封装。

TCP/IP 协议族

实际互联网使用的是 TCP/IP 协议族(四层模型):

TCP/IP 层对应 OSI 层主要协议
应用层5~7 层HTTP、HTTPS、FTP、DNS、SMTP
传输层4 层TCP、UDP
网络层3 层IP、ARP、ICMP
网络接口层1~2 层Ethernet、Wi-Fi

IP 地址与端口

  • IP 地址:32 位二进制(IPv4),标识网络中的主机位置。格式:192.168.1.100
    • 127.0.0.1:本地回环地址,用于本机自测。
    • 0.0.0.0:监听所有网络接口。
    • 255.255.255.255:广播地址。
  • 端口号:0~65535,标识主机上的具体进程/服务。
    • 知名端口(0~1023):HTTP 80、HTTPS 443、SSH 22、FTP 21、SMTP 25。
    • 动态端口(49152~65535):客户端随机分配。

TCP vs UDP

特性TCPUDP
连接面向连接(三次握手)无连接
可靠性保证顺序、无丢失不保证
速度较慢(有确认机制)较快
适用场景Web、文件传输、邮件视频流、DNS、游戏

TCP 三次握手与四次挥手

三次握手(建立连接)

客户端                     服务端
   |   ---SYN(seq=x)--->  |    第一次:客户端发 SYN,进入 SYN_SENT
   |  <--SYN+ACK(seq=y,ack=x+1)--  |   第二次:服务端发 SYN+ACK,进入 SYN_RECV
   |   ---ACK(ack=y+1)--> |    第三次:客户端发 ACK,双方进入 ESTABLISHED

为什么三次? 两次握手无法确认客户端的接收能力;三次握手可以双向确认通信正常。

四次挥手(关闭连接)

主动关闭方                  被动关闭方
   |   ---FIN--->          |    第一次:发送 FIN,进入 FIN_WAIT_1
   |   <--ACK---           |    第二次:回复 ACK,进入 CLOSE_WAIT
   |   <--FIN---           |    第三次:发送 FIN,进入 LAST_ACK
   |   ---ACK--->          |    第四次:回复 ACK,等待 2MSL 后关闭

为什么四次? TCP 是全双工的,关闭时两个方向各需要一次 FIN+ACK。

Socket 抽象层

Socket 是操作系统提供的网络编程接口,对应用程序屏蔽了 TCP/IP 的底层细节。

  • AF_INET:IPv4 网络套接字(最常用)

  • AF_INET6:IPv6 网络套接字

  • AF_UNIX:Unix 域套接字,用于同机进程间通信

  • SOCK_STREAM:TCP 套接字(面向连接,可靠)

  • SOCK_DGRAM:UDP 套接字(无连接,快速)

常用端口速查

import socket

# 根据服务名查端口
print(socket.getservbyname("http"))    # 80
print(socket.getservbyname("https"))   # 443
print(socket.getservbyname("ssh"))     # 22

# 根据端口查服务名
print(socket.getservbyport(80))        # "http"

# 获取本机 IP
print(socket.gethostbyname(socket.gethostname()))

下一节 Socket 编程 将介绍如何用 Python 的 socket 模块实现 TCP/UDP 通信。

最后更新于