|
|
import socket
|
|
|
import threading
|
|
|
import time
|
|
|
|
|
|
class TcpClient(object):
|
|
|
def __init__(self):
|
|
|
# 配置信息
|
|
|
self.udpPort = 54321
|
|
|
self.broadcastAddr = '<broadcast>'
|
|
|
def discoverServers(self):
|
|
|
print("[*] 正在扫描局域网设备...")
|
|
|
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
|
udpSock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
|
|
udpSock.settimeout(2)
|
|
|
|
|
|
udpSock.sendto(b"DISCOVERY_REQUEST", (self.broadcastAddr, self.udpPort))
|
|
|
|
|
|
servers = []
|
|
|
try:
|
|
|
while True:
|
|
|
data, addr = udpSock.recvfrom(1024)
|
|
|
if data.startswith(b"DISCOVERY_RESPONSE"):
|
|
|
# 修正点:正确解析服务端IP和TCP端口
|
|
|
_, hostname, tcp_port = data.decode('utf-8').split(':')
|
|
|
server_ip = addr # 提取IP字符串
|
|
|
servers.append({
|
|
|
'ip': server_ip, # 存储为字符串
|
|
|
'port': int(tcp_port), # 存储为整数
|
|
|
'hostname': hostname
|
|
|
})
|
|
|
print()
|
|
|
except socket.timeout:
|
|
|
pass
|
|
|
finally:
|
|
|
udpSock.close()
|
|
|
return servers
|
|
|
|
|
|
def connectToServer(self, ip, tcp_port):
|
|
|
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
|
try:
|
|
|
# 显式转换类型确保安全
|
|
|
client.connect((str(ip), int(tcp_port))) # :ml-citation{ref="2,3" data="citationList"}
|
|
|
print(f"[+] 已连接到 {ip}:{tcp_port}")
|
|
|
client.send(b"Hello from client!")
|
|
|
response = client.recv(1024)
|
|
|
print(f"服务端响应: {response.decode('utf-8')}")
|
|
|
except Exception as e:
|
|
|
print(f"连接失败: {e}")
|
|
|
finally:
|
|
|
client.close()
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
tcpClient = TcpClient()
|
|
|
servers = tcpClient.discoverServers()
|
|
|
if not servers:
|
|
|
print("[-] 未找到可用服务端")
|
|
|
exit()
|
|
|
|
|
|
print("发现以下设备:")
|
|
|
for i, s in enumerate(servers):
|
|
|
print(f"{i+1}. {s['hostname']} ({s['ip']}:{s['port']})") # 显示格式修正
|
|
|
print(servers)
|
|
|
choice = int(input("请输入要连接的设备编号: ")) - 1
|
|
|
selected = servers[choice]
|
|
|
print(selected['ip'][0], selected['port'],88)
|
|
|
tcpClient.connectToServer(selected['ip'][0], selected['port']) # 传递字符串和整数
|