93 lines
3.4 KiB
Python
93 lines
3.4 KiB
Python
|
|
# -*- coding: utf-8 -*-
|
|||
|
|
import socket
|
|||
|
|
import threading
|
|||
|
|
import time
|
|||
|
|
|
|||
|
|
#SERVER_A = ("127.0.0.1", 10) # 终端IP地址
|
|||
|
|
#LISTEN_B = ("127.0.0.1", 8080) # 本地监听端口,模拟服务端B,使用组网虚拟IP:172.16.1.59:8080
|
|||
|
|
|
|||
|
|
# 从config.txt读取配置
|
|||
|
|
with open('./config.txt', 'r') as f:
|
|||
|
|
lines = f.readlines()
|
|||
|
|
# 第一行为SERVER_A的IP和端口,格式为0.0.0.0:10
|
|||
|
|
server_a_parts = lines[0].strip().split(':')
|
|||
|
|
SERVER_A = (server_a_parts[0], int(server_a_parts[1]))
|
|||
|
|
|
|||
|
|
# 第二行为LISTEN_B的IP和端口,格式为0.0.0.0:10
|
|||
|
|
listen_b_parts = lines[1].strip().split(':')
|
|||
|
|
LISTEN_B = (listen_b_parts[0], int(listen_b_parts[1]))
|
|||
|
|
clients = [] # 保存所有连接到B的客户端
|
|||
|
|
|
|||
|
|
def handle_client(conn, addr):
|
|||
|
|
"""服务端B处理客户端连接"""
|
|||
|
|
print(f"[B] 客户端已连接: {addr}")
|
|||
|
|
clients.append(conn)
|
|||
|
|
try:
|
|||
|
|
while True:
|
|||
|
|
data = conn.recv(1024)
|
|||
|
|
if not data:
|
|||
|
|
break
|
|||
|
|
print(f"[B] 收到客户端消息(一般不用处理): {data!r}")
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"[B] 客户端异常: {e}")
|
|||
|
|
finally:
|
|||
|
|
clients.remove(conn)
|
|||
|
|
conn.close()
|
|||
|
|
print(f"[B] 客户端断开: {addr}")
|
|||
|
|
|
|||
|
|
def start_server_b():
|
|||
|
|
"""启动服务端B"""
|
|||
|
|
global server_b_started
|
|||
|
|
try:
|
|||
|
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|||
|
|
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|||
|
|
s.bind(LISTEN_B)
|
|||
|
|
s.listen(5)
|
|||
|
|
server_b_started = True
|
|||
|
|
print(f"[B] 模拟服务端B已启动,监听 {LISTEN_B}")
|
|||
|
|
while True:
|
|||
|
|
conn, addr = s.accept()
|
|||
|
|
threading.Thread(target=handle_client, args=(conn, addr), daemon=True).start()
|
|||
|
|
except Exception as e:
|
|||
|
|
server_b_started = False
|
|||
|
|
print(f"[B] 服务端B异常: {e}")
|
|||
|
|
|
|||
|
|
def connect_server_a():
|
|||
|
|
"""连接服务端A,并转发数据到B的所有客户端"""
|
|||
|
|
global server_b_started
|
|||
|
|
while True: # 添加外层循环以实现重连
|
|||
|
|
try:
|
|||
|
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|||
|
|
s.connect(SERVER_A)
|
|||
|
|
print(f"[A] 已连接到服务端A: {SERVER_A}")
|
|||
|
|
while True:
|
|||
|
|
# 检查服务端B是否正常启动
|
|||
|
|
if not server_b_started:
|
|||
|
|
print("[B] 警告: 服务端B没有正常启动,可能是使用了本机不存在的IP地址")
|
|||
|
|
data = s.recv(4096)
|
|||
|
|
if not data:
|
|||
|
|
print("[A] 连接关闭")
|
|||
|
|
break
|
|||
|
|
print(f"[A] 收到数据 {len(data)} 字节,转发给B的客户端")
|
|||
|
|
# 转发给所有已连接B的客户端
|
|||
|
|
for c in clients[:]:
|
|||
|
|
try:
|
|||
|
|
c.sendall(data)
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"[B] 转发失败: {e}")
|
|||
|
|
clients.remove(c)
|
|||
|
|
c.close()
|
|||
|
|
s.close() # 正常关闭连接
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"[A] 连接失败: {e}")
|
|||
|
|
print("[A] 10秒后尝试重新连接...")
|
|||
|
|
time.sleep(10) # 等待10秒后重新连接
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
# 服务端B启动状态标志
|
|||
|
|
server_b_started = False
|
|||
|
|
# 启动服务端B
|
|||
|
|
threading.Thread(target=start_server_b, daemon=True).start()
|
|||
|
|
# 启动客户端去连接服务端A
|
|||
|
|
connect_server_a()
|