簡體   English   中英

TCP 通過 IP 連接 Python 中的地址和端口

[英]TCP Connection through IP Addresses & Port in Python

我們正在嘗試在 Python 3.8 中建立 TCP 連接,我們希望每台機器同時成為客戶端和服務器,以便每台機器都可以發送和接收消息。 使用此代碼,我們可以(有時)發送和接收數據,但我們注意到每台機器都可以向IPs列表中的第一個 ip 地址發送消息,但忽略了 rest。

也許有比這更好的方法來建立 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

在這個例子中,每台機器上只有一個服務器和客戶端。 然后,您必須在服務器級別管理將消息重定向到目標客戶端(識別發送消息的客戶端和目標客戶端以將消息尋址到正確的客戶端)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM