我们正在尝试在Python 3.8中建立TCP连接,我们希望每台计算机同时成为客户端和服务器,以便每台计算机都可以发送和接收消息。使用此代码,我们可以(有时)发送和接收数据,但是我们注意到,每台机器都可以将消息发送到IPs
列表中的第一个IP地址,而其余的则被忽略了。
也许有比这更好的方法来建立TCP连接,所以我们可以互相发送数据吗?
全部三个部分(服务器,客户端和共享分发)代码都附加到每台机器正在运行的python程序上。
开始分发:
这里服务器套接字已启动,并且我们为要连接的每个IP地址启动线程。
def start_distributed_sharing(self):
self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.serv.bind(('0.0.0.0', 44445))
self.serv.listen(5)
MAX_CONNECTION = 5
IPs = ['{ip-address}', '{ip-address}', '{ip-address}', ]
client_threads = []
for ip in IPs:
client_threads.append(threading.Thread(target=self.client, args=(ip,)))
for i in range(0, len(client_threads)):
client_threads[i].start()
print("Clients is running")
while True:
conn, addr = self.serv.accept()
server_thread = threading.Thread(target=self.server, args=(conn, addr,))
server_thread.start()
print("New connection to server created!")
服务器:
每台机器启动自己的服务器,并等待客户端连接
def server(self, conn, addr):
while True:
data = ''
try:
data = conn.recv(4096)
except Exception:
print("Server: Lost a connection... Retrying...")
time.sleep(5)
break
if not data: break
try:
data = json.loads(data.decode('utf-8'))
print(data)
except Exception:
print("Server: Could not decode message: ", data)
conn.close()
print('Server: client disconnected')
客户:
客户端在这里尝试使用给定的IP地址连接到服务器
def client(self, ip):
# print(ip)
self.cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while True:
connected = False
while not connected:
try:
print("Client: Connecting to, ", ip)
self.cli.connect((ip, 44445))
connected = True
except Exception:
print('Client: Could not connect to: ', ip, '. Retrying...')
time.sleep(5)
while True:
time.sleep(2)
try:
print("Client: Sending a msg to, ", ip)
self.cli.send(json.dumps({"id": "{PC1}", "height": self.nodes[self.current_leader].node_stats.lastBlockHeight, "latency": self.nodes[self.current_leader].avgLatencyRecords}).encode('utf-8'))
except Exception:
print("Client: Could not send more data to, ", ip)
break
如果我理解正确,那么每个(机器/程序)只需要一台服务器?在这种情况下,我认为每个服务器都需要一个唯一的端口。或者,如果希望每个客户端像客户端/服务器一样与主服务器通信,则可以使用客户端的recv方法。
示例1(将消息发送到服务器并等待响应::
def client(self, ip):
self.cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while True:
connected = False
while not connected:
try:
print("Client: Connecting to, ", ip)
self.cli.connect((ip, 44445))
connected = True
except Exception:
print('Client: Could not connect to: ', ip, '. Retrying...')
time.sleep(5)
while True:
time.sleep(2)
try:
print("Client: Sending a msg to, ", ip)
self.cli.send(json.dumps({"id": "{PC1}", "height": self.nodes[self.current_leader].node_stats.lastBlockHeight, "latency": self.nodes[self.current_leader].avgLatencyRecords}).encode('utf-8'))
except Exception:
print("Client: Could not send more data to, ", ip)
break
# Waiting for server response
response = self.cli.recv(1024)
现在,如果您想要服务器消息事件,则可以创建这样的消息处理程序(对于示例来说,它不是很干净的代码:]
def on_message(self, msg):
print(msg)
def message_handle(self):
while True:
# Waiting for server message
msg = self.cli.recv(1024)
# check is message if valid
self.on_message(msg)
def client(self, ip):
# print(ip)
self.cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while True:
connected = False
while not connected:
try:
print("Client: Connecting to, ", ip)
self.cli.connect((ip, 44445))
connected = True
except Exception:
print('Client: Could not connect to: ', ip, '. Retrying...')
time.sleep(5)
# Connection established start message handler
handler = threading.Thread(target=self.message_handle))
handler.start()
while True:
time.sleep(2)
try:
print("Client: Sending a msg to, ", ip)
self.cli.send(json.dumps({"id": "{PC1}", "height": self.nodes[self.current_leader].node_stats.lastBlockHeight, "latency": self.nodes[self.current_leader].avgLatencyRecords}).encode('utf-8'))
except Exception:
print("Client: Could not send more data to, ", ip)
break
在此示例中,每台计算机上只有一个服务器和客户端。然后,您必须在服务器级别上管理消息到目标客户端的重定向(标识发送消息的客户端和目标客户端以将消息寻址到正确的客户端)。