Вопрос об использовании UDP-сокетов для группового чата Python - PullRequest
2 голосов
/ 20 марта 2019

Вот мой клиентский скрипт на python.Это работает так, что каждый клиент устанавливает TCP-соединение с хост-сервером (в моем случае, с сервером AWS), а затем сервер дает им необходимые адреса, чтобы клиенты могли напрямую общаться друг с другом через UDP.

Но когда я проверяю это с 2 клиентами на 2 разных IP, сообщения не принимаются.Кроме того, если я отправлю «это А» с машины А, а «это Б» с машины БИ, на А появится 2 полученных сообщения, говорящих «От А: это А» и «С Б: это А».(печать находится в функции receiveHandler) Это говорит мне, что с моим сокетом что-то не так.И в этом случае аппарат B не печатал никаких сообщений вообще, что странно.

Любая помощь приветствуется, спасибо.Я поставлю серверный скрипт на всякий случай.

import socket
import threading

class Client:
    socket_peers = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    socket_server = socket.socket()
    peers = []

    def __init__(self, SERVER):
        self.server = SERVER
        self.socket_server.connect(SERVER)
        self.socket_peers.bind(("0.0.0.0", 5000))

    def serverHandler(self):
        while True:
            serverData = self.socket_server.recv(1024)
            serverData = serverData.decode()
            if serverData[0] == "$": # alert message
                print(serverData[1:])
            if serverData[0] == "@": # new peer
                new_peer = (serverData[1:], 5000)
                self.peers.append(new_peer)
            if serverData[0] == "^": # quit
                break

    def sendingHandler(self):
        while True:
            message = str(input(">>"))
            for peer in self.peers:
                self.socket_peers.sendto(message.encode(), peer)

    def receiveHandler(self):
        while True:
            data, addr = self.socket_peers.recvfrom(1024)
            print("From " + str(addr) + ": " + data.decode())

    def run(self):
        serverThread = threading.Thread(target=self.serverHandler)
        sendingThread = threading.Thread(target=self.sendingHandler)
        receiveThread = threading.Thread(target=self.receiveHandler)

        serverThread.start()
        sendingThread.start()
        receiveThread.start()

        serverThread.join()
        sendingThread.join()
        receiveThread.join()

        print("Goodbye.")

    def shutdown(self):
        self.socket_server.close()
        self.socket_peers.close()

if __name__ == '__main__':
    host = "123.456.789.0" # This is where I put my AWS server public IP
    port = 5000
    hostServer = (host, port)
    client = Client(hostServer)
    client.run()
    client.shutdown()

Вот серверный скрипт, который запускается на моем экземпляре AWS.

import socket

class Server:
    sock = socket.socket()
    clients = []
    shutdown = False

    def __init__(self):
        self.sock.bind(("0.0.0.0", 5000))

    def run(self):
        self.sock.listen(100)
        print "Listening for connections... "

        while not self.shutdown:
            conn, addr = self.sock.accept()
            self.clients.append((conn, addr))
            self.broadcastNewPeer(addr)
            self.broadcastAlert("User: " + str(addr[0]) + " has joined.")
            print str(addr[0])

    def broadcastAlert(self, message):
        alert = "$" + message
        for client in self.clients:
            client[0].send(alert.encode())

    def broadcastNewPeer(self, addr):
        peerMsg = "@" + str(addr[0])
        for client in self.clients:
            client[0].send(peerMsg.encode())

    def broadcastForceQuit(self):
        quitMsg = "^"
        for client in self.clients:
            client[0].send(quitMsg.encode())

    def close(self):
        self.shutdown = True
        self.broadcastForceQuit()
        for client in self.clients:
            client[0].close()
        self.sock.close()

if __name__ == '__main__':
    myServer = Server()
    myServer.run()
    print "Goodbye."
...