Socket 编程详解(含 TCP 和 UDP 示例)

Socket 编程详解(含 TCP 和 UDP 示例)


一、什么是 Socket?

Socket(套接字)是计算机网络编程中用于进程间通信的接口,允许不同主机上的程序通过网络发送和接收数据。

你可以把它类比成一根“数据管道”,程序通过这根管道与远程设备进行交流。


二、Socket 的作用和优势

  • 数据传输基础:实现网络通信的核心工具。
  • 跨平台通用:支持几乎所有操作系统和编程语言。
  • 支持多协议:可配合 TCP(可靠)或 UDP(高效)等协议使用。
  • 灵活强大:能处理各种网络通信需求,如网页、聊天、游戏等。

三、Socket 的主要类型

类型 协议 特点 应用场景
TCP Socket TCP 面向连接、可靠传输、一对一通信 网页浏览、文件传输
UDP Socket UDP 无连接、快速传输、支持广播 视频直播、在线游戏

四、Socket 常用方法速查表

4.1 通用方法

方法 作用说明 适用协议
bind((ip,port)) 绑定服务端地址 TCP/UDP
close() 关闭连接 通用

4.2 TCP专用方法

方法 说明
listen(backlog) 启动监听,backlog指定最大排队数
accept() -> (conn, addr) 接受连接,返回新socket对象和客户端地址
connect((ip,port)) 客户端连接服务器
send()/recv() 发送/接收数据

4.3 UDP专用方法

方法 说明
sendto(data, address) 发送数据到指定地址
recvfrom(bufsize) -> (data, addr) 接收数据和发送方地址

五、IP 地址 & 端口号基础

  • IP 地址:标识一台主机(例如 127.0.0.1 表示本地)
  • 端口号:标识主机上的某个程序,取值范围:0~65535
范围 类型
0 - 1023 系统端口
1024 - 49151 注册端口
49152 - 65535 动态端口

六、TCP 编程流程详解(面向连接)

🔹 1. 单次通信示例

TCP 服务器端

from socket import socket, AF_INET, SOCK_STREAM

server_socket = socket(AF_INET, SOCK_STREAM)     # 1. 创建 socket
server_socket.bind(('127.0.0.1', 8888))          # 2. 绑定地址和端口
server_socket.listen(5)                          # 3. 开始监听
print('服务器启动,等待连接...')

client_socket, client_addr = server_socket.accept()  # 4. 等待客户端连接
data = client_socket.recv(1024).decode('utf-8')      # 5. 接收数据
print('收到客户端数据:', data)

client_socket.send('Hello from server!'.encode('utf-8'))  # 6. 发送响应

client_socket.close()
server_socket.close()

TCP 客户端

import socket

client_socket = socket.socket()
client_socket.connect(('127.0.0.1', 8888))             # 连接服务器
print('连接成功')
client_socket.send('Welcome to Python'.encode('utf-8')) # 发送数据
client_socket.close()

🟡 注意:先运行服务器端,再运行客户端!


🔹 2. 多次通信示例(支持对话)

TCP 服务器端

from socket import socket, AF_INET, SOCK_STREAM

server_socket = socket(AF_INET, SOCK_STREAM)
server_socket.bind(('127.0.0.1', 8888))
server_socket.listen(5)
print('服务启动,等待连接...')

client_socket, _ = server_socket.accept()
data = client_socket.recv(1024).decode('utf-8')

while data != 'bye':
    if data:
        print('接收到客户端数据:', data)
    send_data = input('回复客户端:')
    client_socket.send(send_data.encode('utf-8'))
    if send_data == 'bye':
        break
    data = client_socket.recv(1024).decode('utf-8')

client_socket.close()
server_socket.close()

TCP 客户端

import socket

client_socket = socket.socket()
client_socket.connect(('127.0.0.1', 8888))
print('已连接服务器')

info = ''
while info != 'bye':
    msg = input('发送给服务器:')
    client_socket.send(msg.encode('utf-8'))
    if msg == 'bye':
        break
    info = client_socket.recv(1024).decode('utf-8')
    print('服务器回复:', info)

client_socket.close()

七、UDP 编程流程详解(无连接)

🔹 1. 发送方代码

from socket import socket, AF_INET, SOCK_DGRAM

send_socket = socket(AF_INET, SOCK_DGRAM)
data = input('发送内容:')
send_socket.sendto(data.encode('utf-8'), ('127.0.0.1', 8888))  # 发送数据

recv_data, addr = send_socket.recvfrom(1024)
print('接收到回复:', recv_data.decode('utf-8'))

send_socket.close()

🔹 2. 接收方代码

from socket import socket, AF_INET, SOCK_DGRAM

recv_socket = socket(AF_INET, SOCK_DGRAM)
recv_socket.bind(('127.0.0.1', 8888))  # 绑定地址端口

recv_data, addr = recv_socket.recvfrom(1024)
print('收到数据:', recv_data.decode('utf-8'))

reply = input('回复:')
recv_socket.sendto(reply.encode('utf-8'), addr)

recv_socket.close()

🔹 模拟聊天场景

  • 客户咨询者
# 客户咨询者
from socket import socket,AF_INET,SOCK_DGRAM

# (1)创建socket对象
send_socket=socket(AF_INET,SOCK_DGRAM)

while True:
    # (2) 指定接收方IP地址和端口号
    ip_port=('127.0.0.1',8888)
    # (3) 准备发送数据
    data=input('请输入要发送的数据:')   
    # (4) 发送数据
    send_socket.sendto(data.encode('utf-8'),ip_port)
    if data == 'bye':
        break
    # (5) 接收来自接客服的回复数据
    recv_data,addr = send_socket.recvfrom(1024)
    print('客服回复:',recv_data.decode('utf-8'))

# 关闭socket对象
send_socket.close()
  • 客服人员
from socket import socket,AF_INET,SOCK_DGRAM

# (1) 使用socket类创建一个套接字对象
recv_socket=socket(AF_INET,SOCK_DGRAM)
# (2)绑定发送方IP和主机设置的端口号
ip = '127.0.0.1'
port = 8888
recv_socket.bind((ip,port))

while True:
    # (3) 接收来自发送方的数据
    recv_data,addr = recv_socket.recvfrom(1024)
    print('客户说:',recv_data.decode('utf-8'))
    if recv_data.decode('utf-8') == 'bye':
        break
    # (4) 准备回复对方的数据
    data = input('回复:')
    # (5) 回复:
    recv_socket.sendto(data.encode('utf-8'),addr)

# (6) 结束
recv_socket.close()

🟡 注意:UDP编程接收方与发送方启动运行无先后,但先启动运行发送方,数据会丢包


八、总结

特性 TCP UDP
是否连接 需要连接(连接后通信) 无需连接(直接发送数据)
是否可靠 是,数据有序、无丢失 否,可能丢包、乱序
速度 相对较慢 快速
应用场景 文件传输、网页、聊天应用 视频直播、游戏、广播通知

Socket 的工作流程

Socket 的工作流程因协议不同而略有差异,以下是两种常见协议的典型流程:

  • TCP Socket 的工作流程

    1. 服务器端
      • 创建套接字:socket.socket(socket.AF_INET, socket.SOCK_STREAM)

      • 绑定地址和端口:socket.bind((host, port))

      • 开始监听:socket.listen()

      • 接受连接:socket.accept()(返回一个新的套接字和客户端地址)

      • 通信:通过返回的套接字发送和接收数据

      • 关闭连接:socket.close()

    2. 客户端
      • 创建套接字:socket.socket(socket.AF_INET, socket.SOCK_STREAM)

      • 连接到服务器:socket.connect((host, port))

      • 通信:发送和接收数据

      • 关闭连接:socket.close()

  • UDP Socket 的工作流程

    1. 服务器端
      • 创建套接字:socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

      • 绑定地址和端口:socket.bind((host, port))

      • 接收数据:socket.recvfrom(buffer_size)(返回数据和客户端地址)

      • 发送数据:socket.sendto(data, address)

      • 关闭套接字:socket.close()

    2. 客户端
      • 创建套接字:socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

      • 发送数据:socket.sendto(data, address)

      • 接收数据:socket.recvfrom(buffer_size)

      • 关闭套接字:socket.close()

posted @ 2025-05-04 18:59  kyle_7Qc  阅读(2190)  评论(0)    收藏  举报