通信模块
本模块提供网络通信功能,用于在通用任务中进行数据传递。
支持 TCP 和 UDP 两种传输协议,所有消息使用 UTF-8 编码。
Important
端口限制: 所有网络通信端口必须在 50000-51000 范围内。
核心功能
TCP 客户端
- create_tcp_client(ip, port)
Create TCP client (factory function)
- Parameters:
- Returns:
TCP client instance (already connected)
- Return type:
- Raises:
RuntimeError – If connection fails
ValueError – If port is not in allowed range (50000-51000)
Example:
# Method 1: Using create_tcp_client client = create_tcp_client("127.0.0.1", 8080) client.send("Hello Server") response = client.receive() print(f"Received: {response}") client.close() # Method 2: Using with statement (recommended) with create_tcp_client("127.0.0.1", 8080) as client: client.send("Hello Server") response = client.receive() print(f"Received: {response}")
- class TCPClient(ip, port)
Bases:
objectTCP Client class
All messages use UTF-8 encoding. Sends data with 0x03 (x03) as end delimiter appended automatically. Receives data until 0x03 delimiter is encountered.
- END_OF_TEXT = b'\x03'
- __init__(ip, port)
Initialize TCP client
- Parameters:
- Raises:
ValueError – If port is not in allowed range (50000-51000)
- connect()
Connect to server
- Returns:
True if connection successful
- Return type:
- Raises:
RuntimeError – If connection fails
- send(data)
Send data (automatically appends 0x03 delimiter)
- Parameters:
data (
str) – UTF-8 string to send- Returns:
Number of bytes sent (including delimiter)
- Return type:
- Raises:
RuntimeError – If send fails
- receive(timeout=None, buffer_size=4096)
Receive data (until 0x03 delimiter is encountered)
- Parameters:
- Returns:
Received UTF-8 string (without delimiter) None: On timeout or receive failure
- Return type:
- Raises:
RuntimeError – When connection is closed or serious error occurs
- close()
Close connection
TCP 服务器
- create_tcp_server(port, host='0.0.0.0', message_callback=None)
Create TCP server (factory function)
- Parameters:
port (
int) – Port to listen on (must be between 50000-51000)host (
str) – Host address to bind (default 0.0.0.0 listens on all interfaces)message_callback (
Optional[Callable[[str,Tuple],str]]) – Message handler callback function Signature: callback(message: str, client_address: tuple) -> response: str If None, echoes messages by default
- Returns:
TCP server instance (already started)
- Return type:
- Raises:
RuntimeError – If server fails to start
ValueError – If port is not in allowed range (50000-51000)
Example:
# Method 1: Default echo mode server = create_tcp_server(8080) # Server runs in background, echoing all received messages # Call server.stop() when done # Method 2: Custom message handler def my_handler(msg, addr): return f"Processed: {msg}" server = create_tcp_server(8080, message_callback=my_handler) # Method 3: Using with statement (recommended) with create_tcp_server(8080) as server: # Server runs in background import time time.sleep(10) # Run for 10 seconds # Automatically closes # Method 4: Manual send/receive server = create_tcp_server(8080) # Wait for clients to connect... clients = server.get_connected_clients() if clients: # Send to first client server.send("Hello Client", clients[0]) # Receive from first client (10 second timeout) msg = server.receive(clients[0], timeout=10.0)
- class TCPServer(port, host='0.0.0.0')
Bases:
objectTCP Server class
All messages use UTF-8 encoding. Sends data with 0x03 (x03) as end delimiter appended automatically. Receives data until 0x03 delimiter is encountered.
- END_OF_TEXT = b'\x03'
- __init__(port, host='0.0.0.0')
Initialize TCP server
- Parameters:
- Raises:
ValueError – If port is not in allowed range (50000-51000)
- start(message_callback=None)
Start the server
- Parameters:
message_callback (
Optional[Callable[[str,Tuple],str]]) – Message handler callback function Signature: callback(message: str, client_address: tuple) -> response: str Return value will be sent as response to client If None, echoes the message back by default- Raises:
RuntimeError – If server fails to start
Example:
def handle_message(msg, addr): return f"Server received: {msg}" server = TCPServer(8080) server.start(message_callback=handle_message)
- send(data, client_address=None)
Send data to specific client (automatically appends 0x03 delimiter)
- Parameters:
- Returns:
Number of bytes sent (including delimiter)
- Return type:
- Raises:
RuntimeError – If send fails
- receive(client_address, timeout=None, buffer_size=4096)
Receive data from specific client (until 0x03 delimiter is encountered)
Note: This method blocks and may conflict with automatic handler threads. Recommend using message_callback to handle received messages.
- Parameters:
- Returns:
Received UTF-8 string (without delimiter) None: On timeout or receive failure
- Return type:
- Raises:
RuntimeError – When client is not connected or serious error occurs
- get_connected_clients()
Get list of all connected client addresses
- Returns:
List of client addresses
- Return type:
- send_to_all(message)
Send message to all connected clients (broadcast)
- Parameters:
message (
str) – UTF-8 string to send- Raises:
RuntimeError – If send fails
- stop()
Stop the server
UDP Socket
- create_udp_socket(port, host='0.0.0.0')
Create UDP socket (factory function)
- Parameters:
- Returns:
UDP socket instance (already bound)
- Return type:
- Raises:
RuntimeError – If socket fails to bind
ValueError – If port is not in allowed range (50000-51000)
Example:
# Method 1: Basic send/receive sock = create_udp_socket(50001) # Send to another UDP endpoint sock.send("Hello UDP", ("192.168.1.100", 50002)) # Receive data (10 second timeout) result = sock.receive(timeout=10.0) if result: message, sender_addr = result print(f"Received '{message}' from {sender_addr}") sock.close() # Method 2: Using with statement (recommended) with create_udp_socket(50001) as sock: sock.send("Hello UDP", ("192.168.1.100", 50002)) result = sock.receive(timeout=5.0) if result: message, sender_addr = result print(f"Received: {message}") # Method 3: Broadcast with create_udp_socket(50001) as sock: sock.enable_broadcast() sock.send("Broadcast message", ("255.255.255.255", 50002)) # Method 4: Reply to sender with create_udp_socket(50001) as sock: result = sock.receive() if result: message, sender_addr = result # Reply to sender sock.send(f"Echo: {message}", sender_addr)
- class UDPSocket(port, host='0.0.0.0')
Bases:
objectUDP Socket class
All messages use UTF-8 encoding. Supports both unicast and broadcast communication.
- __init__(port, host='0.0.0.0')
Initialize UDP socket
- Parameters:
- Raises:
ValueError – If port is not in allowed range (50000-51000)
- bind()
Bind socket to port
- Raises:
RuntimeError – If bind fails
- Return type:
- send(data, address)
Send data to specified address
- Parameters:
- Returns:
Number of bytes sent
- Return type:
- Raises:
RuntimeError – If send fails
ValueError – If destination port is not in allowed range
- receive(timeout=None, buffer_size=4096)
Receive data from socket
- Parameters:
- Returns:
(message, (sender_ip, sender_port)) None: On timeout or receive failure
- Return type:
- Raises:
RuntimeError – When socket is not bound or serious error occurs
- enable_broadcast()
Enable broadcast mode for the socket
- Raises:
RuntimeError – If socket is not initialized
- Return type:
使用说明
端口限制
所有网络模块(TCP 和 UDP)的端口必须在 50000-51000 范围内:
# ✓ 正确 - 端口在允许范围内
tcp_server = create_tcp_server(50001)
tcp_client = create_tcp_client("127.0.0.1", 50500)
udp_socket = create_udp_socket(51000)
# ✗ 错误 - 端口超出范围,将抛出 ValueError
tcp_server = create_tcp_server(8080) # ValueError
udp_socket = create_udp_socket(5000) # ValueError
TCP 协议说明
编码: UTF-8
结束符:
\x03(End of Text)超时行为:
receive()超时返回None,不抛出异常连接模式: 面向连接,可靠传输
UDP 协议说明
编码: UTF-8
无结束符: UDP 是消息边界保留的协议
超时行为:
receive()超时返回None连接模式: 无连接,不保证可靠传输
支持广播: 可启用广播模式发送到多个接收者
基本示例
TCP 客户端示例
from daystar_api.tcp_client import create_tcp_client
# 创建客户端并连接(使用 with 语句)
with create_tcp_client("192.168.1.100", 50001) as client:
# 发送消息
client.send("Hello Server")
# 接收响应
response = client.receive(timeout=5.0)
if response:
print(f"Received: {response}")
TCP 服务器示例
from daystar_api.tcp_server import create_tcp_server
# 定义消息处理函数
def handle_message(msg, client_addr):
print(f"Received from {client_addr}: {msg}")
return f"Echo: {msg}"
# 创建并启动服务器
server = create_tcp_server(50001, message_callback=handle_message)
# 服务器在后台运行...
# 需要时停止服务器
server.stop()
UDP Socket 基本示例
from daystar_api.udp_socket import create_udp_socket
# 发送方
with create_udp_socket(50001) as sender:
sender.send("Hello UDP", ("192.168.1.100", 50002))
# 接收方
with create_udp_socket(50002) as receiver:
result = receiver.receive(timeout=10.0)
if result:
message, sender_addr = result
print(f"Received '{message}' from {sender_addr}")
# 回复发送者
receiver.send(f"Echo: {message}", sender_addr)
UDP 广播示例
from daystar_api.udp_socket import create_udp_socket
# 广播发送方
with create_udp_socket(50001) as broadcaster:
broadcaster.enable_broadcast()
broadcaster.send("Broadcast message", ("255.255.255.255", 50002))
# 广播接收方(多个实例可同时接收)
with create_udp_socket(50002) as receiver:
result = receiver.receive(timeout=5.0)
if result:
message, sender_addr = result
print(f"Broadcast received: {message}")
高级用法
TCP 服务器手动发送
server = create_tcp_server(50001)
# 获取所有已连接的客户端
clients = server.get_connected_clients()
# 发送到特定客户端
if clients:
server.send("Hello Client", clients[0])
# 广播到所有客户端
server.send_to_all("Broadcast message")
UDP 实时通信
import time
with create_udp_socket(50001) as sock:
# 持续接收并回复
while True:
result = sock.receive(timeout=1.0)
if result:
message, sender = result
print(f"Got: {message}")
sock.send(f"ACK: {message}", sender)
# 定期发送心跳
sock.send("heartbeat", ("192.168.1.100", 50002))
time.sleep(1)
协议选择建议
TCP 适用场景
需要可靠传输的场景
大量数据传输
客户端-服务器架构
需要保证消息顺序
UDP 适用场景
实时性要求高,可容忍少量丢包
广播/组播通信
无状态通信
简单的请求-响应模式
发现和心跳检测
错误处理
所有通信模块的错误处理遵循统一规范:
from daystar_api.tcp_client import create_tcp_client
try:
# 端口超出范围
client = create_tcp_client("127.0.0.1", 8080)
except ValueError as e:
print(f"端口错误: {e}")
try:
# 连接失败
client = create_tcp_client("192.168.1.100", 50001)
except RuntimeError as e:
print(f"连接失败: {e}")
try:
# 发送失败
client.send("data")
except RuntimeError as e:
print(f"发送失败: {e}")