2016-04-01 44 views
1

Eşler arası sohbet uygulaması oluşturmakla görevlendirildim, ancak aslında ileti gönderirken sorun yaşıyorum. Temel olarak, kullanıcının bağlanmak istediği kişinin hem IP'si hem de portu istenmeli ve daha sonra sürekli olarak mesaj gönderip alması istenmelidir. Ancak, programı çalıştırdıktan hemen sonra "rastgele" bir bağlantı yapılmakta gibi görünüyor.Python Peer-to-Peer Sohbeti (Yuvalar)

Hata:

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) 

Neden port 2811 tarihinde bir bağlantı var? Sanki program kendi kendine bağlanıyormuş gibi.

Kodu:

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

Argümanları doğrudan kurucu – winklerrr

cevap

4

Bu priz ve bağlantı noktaları hakkında bir yanlış anlama. Sunucu (ChatListener), bağlantı için 5000 numaralı bağlantı noktasında DİNLEME'dir. Sunucunun telefon numarası olarak 127.0.0.1:5000 olduğunu düşünün. Ancak, istemci (ChatSender) sonunda istediği herhangi bir bağlantı noktasını kullanmakta serbesttir ve genellikle başka bir şey için ayrılmayan birini seçer. İstemcinin aradığı farklı bir "telefon numarası" olacaktır. Yazdırdığınız şey, sunucunun "telefon numarası" (127.0.0.1:5000) değil, aynı bağlantı noktasında olmayan gelen çağrı için "arayan kimliği" (127.0.0.1:2811) değil.

Açıklayıcı bir örnek. Bir an için gönderenin aslında farklı bir makinede olduğunu ve bazı farklı IP adreslerinde 127.0.0.2 olduğunu düşünün. İstemci, 127.0.0.1:5000’e bağlanmaya çalışan bir soket başlatır. Bağlantıyı yapmak için 2811'i söyleyen çeşitli bir port tahsis ediyor. Başarılı olursa, sunucu 127.0.0.2:2811'e bağlanır. Müşterinin bazı verileri göndermek istediği zaman, bunu 127.0.0.1:5000'e gönderecek. Ancak, sunucu istemciye veri göndermek istediğinde, 127.0.0.2:2811 tarihinde bunu gerçekleştirecektir. Bu örnek net değilse ve daha fazla açıklığa kavuşturmaya çalışalım.

+0

Ah içinden geçebilirdiniz, şimdi anladığımı düşünüyorum. Teşekkürler! Temel olarak, IP/Port çifti dinlemek için gereklidir. Sohbet 1 Sohbet 2 ile konuşmak istediyse, Sohbet 2'nin IP/Bağlantı Noktası'na ihtiyacı vardır, böylece Sohbet 2'yi dinleyebilir. Sohbet 2, Sohbet 1'e geri dönmek istiyorsa, Sohbet 1'in IP'sine ihtiyacı olacaktır. Bağlantı Noktası bu nedenle Sohbet 1'i dinleyebilir. --- Şimdi bu kodu 2 farklı kullanıcı için çalıştırmak istediğimi farz edelim ki birbirleriyle konuşabilirler. Kullanıcı başına sadece bir soket oluşturmak ve hem dinleme hem de gönderme için kullanmak mümkün mü? – SlashTag

+0

Sorun değil! Kodunuzu tam olarak çalıştığınızda, bunun gibi olacağını hayal edin: Sohbet 1, Sohbet 2 ile konuşmak istiyor. Sohbet 2, bilinen bir bağlantı noktasında çalışan bir sunucu (dinleyici) iş parçacığına sahip olmalıdır. Sohbet 1, dinleyicinin IP/portuna bir bağlantı başlatır. Oradan iki yönlü iletişim sadece o soketi kullanarak devam edebilir. Sohbet 1'de, sokette alınan veriyi dinleyen bir iplik ve bu sokette veri ileten bir başka iplik bulunur. Bunu Sohbet 2 için aynalayın. – Christian

+0

Mükemmel. Yani sadece açıklığa kavuşturmak için, sadece iki farklı makine arasında gönderme ve alma için 1 soket ve 1 soket kullanabilirim (bunun böyle olduğunu varsayın, fakat test etmek için mutlaka gerekli değildir) – SlashTag