概述
Socket 是计算机网络中用于实现进程间通信的一种技术。简而言之,它是一个端点,用于发送或接收数据。这些数据可以在同一台计算机上的进程之间,或者在不同计算机上的进程之间进行传输。
socket
是 Python 中的一个标准库,它提供了低级的网络通信功能。基于该库,开发者可以实现 TCP、UDP 以及其他类型的网络协议的客户端和服务端程序。
socket
库的历史可以追溯到 Unix 操作系统的早期。在 Unix 中,socket 被用作进程间通信 (IPC) 的一种方式。随着互联网的发展,socket 逐渐被应用于网络通信。Python 的 socket
库提供了对这一功能的高级封装,使得开发网络应用变得更为简单。
工作原理
socket
网络通信最常见的模型是客户端 - 服务器模型。客户端是请求服务的实体,而服务器是提供服务的实体。Socket 允许这两个实体进行通信。
客户端 : 创建 Socket → 连接到服务器 → 交换数据 → 关闭 Socket
服务器 : 创建 Socket → 绑定到特定地址和端口 → 监听连接 → 接受客户端连接 → 交换数据 → 关闭 Socket
socket
主要被用于:
创建网络服务器和客户端。
实现多种网络协议,如 TCP 和 UDP。
进行低级的网络通信,如发送原始套接字数据。
它解决了开发者在进行网络通信时的底层细节问题,如地址转换、数据传输等。
协议类型
流式 Socket (SOCK_STREAM) : 提供了一个可靠的、面向连接的字节流。这是最常用的 Socket 类型,TCP 协议就是基于这种 Socket。
数据报 Socket (SOCK_DGRAM) : 提供了一种无连接的、不可靠的数据传输方式。UDP 协议就是基于这种 Socket。
原始 Socket (SOCK_RAW) : 允许直接访问底层协议,通常用于开发新的通信协议。
地址家族
AF_INET (IPv4) : 最常用的地址家族,用于 Internet 通信。
AF_INET6 (IPv6) : 下一代 Internet 地址家族。
AF_UNIX : 用于同一台机器上的进程间通信。
生命周期
graph LR;
A[创建 Socket] --> B[绑定 Socket到地址和端口];
B --> C[开始监听传入的连接];
C --> D[接受连接请求];
D --> E[进行数据传输];
E --> F[关闭 Socket];
创建 : 使用 socket.socket()
创建一个新的 Socket 对象。
绑定 : 使用 bind()
方法将 Socket 绑定到特定的地址和端口。
监听 : 使用 listen()
方法开始监听传入的连接。
接受连接 : 使用 accept()
方法接受一个连接。
数据传输 : 使用 send()
和 recv()
方法进行数据传输。
关闭 : 使用 close()
方法关闭 Socket。
基础操作
由于 socket
是 Python 的标准库,无需额外安装。
支持协议
socket
库支持多种协议,用于不同的网络通信场景。
# 服务器
import socket
server_socket = socket.socket(socket. AF_INET , socket. SOCK_STREAM )
server_socket.bind(( 'localhost' , 8080 ))
server_socket.listen( 5 )
print ( "服务器正在监听..." )
client_socket, addr = server_socket.accept()
print ( f "连接来自 { addr } " )
data = client_socket.recv( 1024 )
print ( f "接收到的数据: { data.decode( 'utf-8' ) } " )
client_socket.send( "谢谢你!" .encode( 'utf-8' ))
client_socket.close()
server_socket.close()
# 客户端
import socket
client_socket = socket.socket(socket. AF_INET , socket. SOCK_STREAM )
client_socket.connect(( 'localhost' , 8080 ))
client_socket.send( "你好,服务器!" .encode( 'utf-8' ))
data = client_socket.recv( 1024 )
print ( f "接收到的数据: { data.decode( 'utf-8' ) } " )
client_socket.close()
TCP 示例
graph LR
subgraph TCP服务器
A[创建Socket] --> B[绑定到地址和端口]
B --> C[监听连接请求]
C --> D[接受连接]
D --> E[接收数据]
E --> F[处理数据]
F --> G[发送响应]
G --> E
E --> H[关闭连接]
H --> D
end
subgraph TCP客户端
I[创建Socket] --> J[连接到服务器]
J --> K[发送数据]
K --> L[接收响应]
L --> M[处理响应]
M --> K
K --> N[关闭连接]
end
A --> I
服务器
import socket
# 步骤1:创建 TCP Socket
server_socket = socket.socket(socket. AF_INET , socket. SOCK_STREAM )
# 步骤2:绑定 Socket 到一个特定的 IP 地址和端口
server_address = ( 'localhost' , 12345 )
server_socket.bind(server_address)
# 步骤3:监听传入的连接请求
server_socket.listen( 5 )
print ( "TCP 服务器启动,等待连接..." )
while True :
# 步骤4:接受客户端的连接请求
client_socket, client_address = server_socket.accept()
print ( f "接受来自 { client_address } 的连接" )
# 步骤5:与客户端建立通信
while True :
data = client_socket.recv( 1024 )
if not data:
break
# 步骤6:接收和发送数据
data = data.decode( 'utf-8' )
print ( f "接收到来自客户端的数据: { data } " )
response = f "你好,
客户端
import socket
# 步骤1:创建 TCP Socket
client_socket = socket.socket(socket. AF_INET , socket. SOCK_STREAM )
# 步骤2:连接到服务器的 IP 地址和端口
server_address = ( 'localhost' , 12345 )
client_socket.connect(server_address)
while True :
# 步骤3:发送数据给服务器
message = input ( "请输入要发送的消息 (输入 'exit' 退出): " )
if message == 'exit' :
break
client_socket.send(message.encode( 'utf-8' ))
# 步骤4:接收来自服务器的响应数据
data = client_socket.recv( 1024 )
# 步骤5:处理服务器的响应数据
data = data.decode( 'utf-8' )
print ( f "接收到服务器的响应: { data } " )
# 步骤6:关闭与服务器的连接
client_socket.close()
UDP 示例
graph LR
subgraph UDP服务器
A[创建Socket] --> B[绑定到地址和端口]
B --> C[接收数据]
C --> D[处理数据]
D --> E[发送响应]
E --> C
end
subgraph UDP客户端
F[创建Socket] --> G[发送数据]
G --> H[接收响应]
H --> I[处理响应]
I --> G
end
A --> F
服务端
import socket
# 步骤1:创建 UDP Socket
server_socket = socket.socket(socket. AF_INET , socket. SOCK_DGRAM )
# 步骤2:绑定 Socket 到一个特定的 IP 地址和端口
server_address = ( 'localhost' , 12345 )
server_socket.bind(server_address)
print ( "UDP 服务器启动,等待数据..." )
while True :
# 步骤3:接收客户端发送的数据
data, client_address = server_socket.recvfrom( 1024 )
# 步骤4:处理客户端数据
data = data.decode( 'utf-8' )
print ( f "接收到来自 { client_address } 的数据: { data } " )
# 步骤5:为客户端发送响应(如果需要)
response = f "你好,客户端!你发送了: { data } "
server_socket.sendto(response.encode( 'utf-8' ), client_address)
# 步骤6:关闭 Socket(这里永远不会执行到)
server_socket.close()
客户端
import socket
# 步骤1:创建 UDP Socket
client_socket = socket.socket(socket. AF_INET , socket. SOCK_DGRAM )
# 服务器地址和端口
server_address = ( 'localhost' , 12345 )
while True :
# 步骤2:发送数据给服务器
message = input ( "请输入要发送的消息 (输入 'exit' 退出): " )
if message == 'exit' :
break
client_socket.sendto(message.encode( 'utf-8' ), server_address)
# 步骤3:接收来自服务器的响应数据
data, server_address = client_socket.recvfrom( 1024 )
# 步骤4:处理服务器的响应数据
data = data.decode( 'utf-8' )
print ( f "接收到服务器的响应: { data } " )
# 步骤5:关闭 Socket
client_socket.close()
常用方法
方法 描述 socket() 创建一个新的 socket bind() 绑定到一个地址和端口 listen() 开始监听连接 accept() 接受一个新的连接 connect() 连接到一个服务器 send() 发送数据 recv() 接收数据 close() 关闭 socket
深入探索
高级功能
非阻塞 Sockets
import socket
s = socket.socket(socket. AF_INET , socket. SOCK_STREAM )
s.setblocking( False )
套接字选项
s.setsockopt(socket. SOL_SOCKET , socket. SO_REUSEADDR , 1 )
超时
s.settimeout( 5.0 )