[通过Python中IP地址和端口的TCP连接

问题描述 投票:0回答:1

我们正在尝试在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
python python-3.x tcp
1个回答
0
投票

如果我理解正确,那么每个(机器/程序)只需要一台服务器?在这种情况下,我认为每个服务器都需要一个唯一的端口。或者,如果希望每个客户端像客户端/服务器一样与主服务器通信,则可以使用客户端的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

在此示例中,每台计算机上只有一个服务器和客户端。然后,您必须在服务器级别上管理消息到目标客户端的重定向(标识发送消息的客户端和目标客户端以将消息寻址到正确的客户端)。

© www.soinside.com 2019 - 2024. All rights reserved.