2016-04-01 42 views
1

私はピアツーピアチャットアプリケーションの作成を担当されていますが、実際にメッセージを送信するのに問題があります。Pythonピアツーピアチャット(ソケット)

本質的に、接続する相手のIPとポートの両方を入力する必要があり、メッセージを連続的に送信/受信する必要があります。

ただし、プログラムを実行した直後に「ランダム」接続が行われているようです。

エラー:

Please enter the address you would like to connect on: 127.0.0.1 
Please enter the port you would like to connect on: 5000 
You: Established connection with: ('127.0.0.1', 2811) 

なぜポート2811での接続がありますか?まるでプログラムがそれ自身に接続しているかのようです。

コード:

import socket 
import threading 

LOCALHOST = '127.0.0.1' 
BUFFER_SIZE = 1024 

def main(): 

    class ChatListener(threading.Thread): 

     def __init__(self): 
      threading.Thread.__init__(self) 
      self.port = None 

     def run(self): 
      listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
      listen_socket.bind((LOCALHOST, self.port)) 
      listen_socket.listen(1) 

      while True: 

       connection, address = listen_socket.accept() 

       print("Established connection with: ", address) 

       message = connection.recv(BUFFER_SIZE) 
       print("Them: ", message) 

    class ChatSender(threading.Thread): 

     def __init__(self): 
      threading.Thread.__init__(self) 
      self.address = None 
      self.port = None 

     def run(self): 
      send_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
      send_socket.connect((self.address, self.port)) 

      while True: 

       message = input("You: ") 

       if message.lower() == "quit": 
        break 
       else: 
        try: 
         send_socket.sendall(message) 
        except: 
         Exception 

    ip = input("Please enter the address you would like to connect on: ") 
    port = int(input("Please enter the port you would like to connect on: ")) 

    chat_listener = ChatListener() 
    chat_listener.port = port 
    chat_listener.start() 

    chat_sender = ChatSender() 
    chat_sender.address = ip 
    chat_sender.port = port 
    chat_sender.start() 

if __name__ == "__main__": 
    main() 
+0

あなたはコンストラクタで引数を直接渡すことができました – winklerrr

答えて

4

これは、ソケットおよびポートに関する誤解です。サーバー(ChatListener)は接続のためにポート5000でLISTENINGしています。 127.0.0.1:5000をサーバーの電話番号とします。しかし、クライアント(ChatSender)は、最後に任意のポートを自由に使用することができ、通常は別のポートに割り当てられていないポートを選択します。クライアントは、呼び出し元とは異なる「電話番号」を持ちます。表示されているのは、サーバーの「電話番号」(127.0.0.1:5000)ではなく、同じポートにない着信コール(127.0.0.1:2811)の「発信者ID」です。

ここに明確な例があります。送信者が別のIPアドレス、例えば127.0.0.2で実際に別のマシンにいるとしばらく考えてみましょう。クライアントはソケットを開始し、127.0.0.1:5000に接続しようとします。接続を確立するために、その他のポート、たとえば2811を割り当てます。成功すると、サーバーは127.0.0.2:2811に接続されます。クライアントが何らかのデータを送信したい場合はいつでも、それを127.0.0.1:5000に送信します。しかし、サーバーがクライアントにデータを送り返したい場合はいつでも、127.0.0.2:2811でこれを行う予定です。この例が不明な場合は教えてください。私はさらに明確にしようとします。

+0

ああ、今私はそれを理解していると信じています。ありがとう! 本質的に、IP /ポートのペアはリスニングに必要です。 チャット1がチャット2と話をしたい場合、チャット2のIP /ポートが必要です。 同様に、チャット2がチャット1に返答したい場合、チャット1のIP /ポートでチャット1を聞くことができます。 --- ここでは、2人の異なるユーザーにこのコードを実行して、お互いに話してもらいたいとします。ユーザーごとに1つのソケットを作成し、それをリスニングと送信の両方に使用することは可能ですか? – SlashTag

+0

問題ありません!チャット1は、チャット2と話したがっています。チャット2には、すでに既知のポートで実行されているサーバー(リスナー)スレッドが必要です。チャット1は、そのリスナーのIP /ポートへの接続を開始します。そこから、そのソケットだけを使用して双方向通信を進めることができます。チャット1は、受信したデータをソケット上でリスンする1つのスレッドと、そのソケット上のデータを送信する別のスレッドを持ちます。チャット2のミラー。 – Christian

+0

優秀。だから、明確にするために、私は1つのソケットと1つのソケットを2つの異なるマシン間で送受信するためにのみ使うことができます(これが当てはまると仮定しますが、テストするためには必然です) – SlashTag