You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多客户端-服务器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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:47:53