多客户端-服务器Socket程序中如何为服务器分配n个端口并追踪连接端口?
解决方案:为服务器配置多端口并追踪连接端口
我来帮你搞定这个需求!要实现每台服务器使用多个端口,并且能明确知道客户端是通过哪个端口和服务器建立连接的目标,我们需要对现有代码做几个关键调整,下面是具体的修改方案和完整代码:
关键改动说明
- 为每台服务器分配多端口:新增
SERVER_PORT_COUNT变量,控制每台服务器的端口数量(比如设置为3,每台服务器就有3个可用端口) - 服务器多端口监听:让每个服务器启动多个线程,分别监听不同的端口
- 客户端随机选择服务器端口:客户端不再只选固定的
5000+id,而是从目标服务器的可用端口列表里随机选一个 - 完善日志输出:在服务器收到消息时,明确打印出客户端连接的具体端口
- 修正CSV生成时机:原来的代码一开始就生成空CSV,现在改成在有连接数据后按需生成,避免无效空文件
修改后的完整代码
import queue import socket import random import threading import pandas as pd UDP_IP = "127.0.0.1" num_server = 3 num_client = 7 # 定义每台服务器的端口数量,可按需调整 SERVER_PORT_COUNT = 3 server_thread_list = [] client_thread_list = [] sid = [] sip = [] dip = [] connect = [] l_info = [] s_port = [] topology_buffer = queue.Queue() # 存储每台服务器的可用端口列表,key是服务器id,value是端口列表 server_ports = {} def create_csv(): source_mac = sid source_ip = sip dest_mac = connect destination_ip = dip link_info = l_info source_portno = s_port df = pd.DataFrame({ "Source_MAC": source_mac, "Source_IP": source_ip, "Source_Port_No": source_portno, "Dest_MAC": dest_mac, "Dest_IP": destination_ip, "Link_Info": link_info }) print("=== 连接信息CSV内容 ===") print(df) df.to_csv("network.csv", index=False) print("CSV文件已生成:network.csv") def server_port_listener(server_id, port): """单个服务器端口的监听线程""" soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) soc.bind((UDP_IP, port)) while True: data, addr = soc.recvfrom(1024) client_id = data.decode() # 生成带后缀的服务器标识(比如S0a、S1b) port_index = list(server_ports[server_id]).index(port) server_identifier = f"S{server_id}{chr(ord('a') + port_index)}" # 打印符合要求的日志 print(f"Server {server_identifier} received message from {client_id} at port number {port}.") # 存入拓扑缓冲区 topology_buffer.put_nowait(f"{server_identifier}<-->{client_id}") # 收集CSV数据 sid.append(server_identifier) ser_ip = f'192.168.1.{random.randint(0, 255)}' sip.append(ser_ip) s_port.append(port) connect.append(client_id) dest_ip = f'192.168.1.{random.randint(0, 255)}' dip.append(dest_ip) # 自定义连接状态信息,可按需修改 l_info.append("Connection Established") def server(id): """启动服务器的所有端口监听线程""" # 为当前服务器生成连续的端口列表 start_port = 5000 + id * SERVER_PORT_COUNT ports = list(range(start_port, start_port + SERVER_PORT_COUNT)) server_ports[id] = ports print(f"Server {id} 启动,监听端口:{ports}") for port in ports: t = threading.Thread(target=server_port_listener, args=(id, port)) server_thread_list.append(t) t.start() def client(id): """客户端线程:随机选择服务器和对应的端口发送消息""" client_id = f"C{id}" # 随机选择一台服务器 target_server_id = random.randint(0, num_server - 1) # 从目标服务器的可用端口里随机选一个 target_port = random.choice(server_ports[target_server_id]) soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) soc.sendto(client_id.encode(), (UDP_IP, target_port)) print(f"客户端 {client_id} 连接到服务器 {target_server_id} 的端口 {target_port}") soc.close() def topology(): """拓扑信息打印线程""" while True: link = topology_buffer.get() print(f"拓扑连接:{link}") # 先启动所有服务器,确保端口列表已初始化 for i in range(num_server): server(i) # 启动客户端线程 for i in range(num_client): t = threading.Thread(target=client, args=(i,)) client_thread_list.append(t) t.start() # 启动拓扑线程 topology_thread = threading.Thread(target=topology) topology_thread.start() # 手动触发生成CSV,输入"save"即可生成 print("\n输入'save'并回车可生成连接信息CSV文件") while True: cmd = input().strip() if cmd.lower() == "save": create_csv() break
代码运行效果示例
启动代码后,你会看到类似这样的输出:
Server 0 启动,监听端口:[5000, 5001, 5002] Server 1 启动,监听端口:[5003, 5004, 5005] Server 2 启动,监听端口:[5006, 5007, 5008] 客户端 C0 连接到服务器 2 的端口 5007 Server S2b received message from C0 at port number 5007. 拓扑连接:S2b<-->C0 客户端 C1 连接到服务器 0 的端口 5001 Server S0a received message from C1 at port number 5001. 拓扑连接:S0a<-->C1 输入'save'并回车可生成连接信息CSV文件
输入save后,会生成包含所有连接端口信息的network.csv文件,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Sakshi
相关产品推荐
相关产品推荐

