82 行
2.7 KiB
Python
82 行
2.7 KiB
Python
import socket
|
|
import threading
|
|
|
|
|
|
def handle_client(conn, addr):
|
|
"""处理单个客户端连接(在独立线程中运行)。"""
|
|
print(f"✅ 客户端已连接: {addr}")
|
|
try:
|
|
# 接收数据循环
|
|
while True:
|
|
# 接收数据(缓冲区大小为 1024 字节)
|
|
data = conn.recv(1024)
|
|
|
|
# 如果没有收到数据,说明客户端已断开连接
|
|
if not data:
|
|
print(f"客户端已断开连接: {addr}")
|
|
break
|
|
|
|
# 解码并打印收到的消息
|
|
message = data.decode('utf-8')
|
|
print(f"📥 收到来自 {addr} 的消息: {message}")
|
|
|
|
# 可选:向客户端发送确认回复
|
|
response = f"服务器已收到: {message}"
|
|
conn.sendall(response.encode('utf-8'))
|
|
print(f"📤 已向 {addr} 发送确认回复。")
|
|
except Exception as e:
|
|
print(f"❌ 与 {addr} 通信发生错误: {e}")
|
|
finally:
|
|
# 关闭该客户端连接
|
|
conn.close()
|
|
print(f"与 {addr} 的连接已关闭。")
|
|
|
|
|
|
def tcp_server():
|
|
# --- 配置区域 ---
|
|
HOST = '0.0.0.0' # 监听所有网络接口
|
|
PORT = 30008 # 与客户端保持一致的端口
|
|
# -----------------
|
|
|
|
# 用于指示服务是否正在运行(便于后续扩展为可关闭)
|
|
server_socket = None
|
|
try:
|
|
# 1. 创建 TCP Socket 对象
|
|
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
|
|
# 设置 SO_REUSEADDR 选项,允许重用地址和端口
|
|
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
|
|
# 2. 绑定地址和端口
|
|
server_socket.bind((HOST, PORT))
|
|
|
|
# 3. 开始监听连接(backlog 调大以支持并发等待队列)
|
|
server_socket.listen(5)
|
|
print(f"🚀 服务器正在监听 {HOST}:{PORT} ...(支持并发连接)")
|
|
print("等待客户端连接...")
|
|
|
|
# 4. 循环接受客户端连接,每来一个连接就启动一个新线程
|
|
while True:
|
|
conn, addr = server_socket.accept()
|
|
client_thread = threading.Thread(
|
|
target=handle_client,
|
|
args=(conn, addr),
|
|
daemon=True,
|
|
)
|
|
client_thread.start()
|
|
print(f"🧵 当前活跃客户端线程数: {threading.active_count() - 1}")
|
|
|
|
except KeyboardInterrupt:
|
|
print("\n⛔ 收到中断信号,正在关闭服务器...")
|
|
except Exception as e:
|
|
print(f"❌ 发生错误: {e}")
|
|
finally:
|
|
# 5. 关闭监听套接字
|
|
if server_socket:
|
|
server_socket.close()
|
|
print("服务器已关闭。")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
tcp_server()
|