2010-11-21 4 views
1

Als Übung suchte ich nach einem einfachen Python-Chat-Client-Server-System zu ändern und zu spielen mit. Der erste schwerwiegende Fehler, den ich im System fand, war, dass er eine einzige TCP-Verbindung für die Kommunikation zwischen Server und Client verwendete. Die zweite war, dass Sie nur zwei Personen (eine mit dem Client und die andere mit dem Server) kommunizieren können. Drittens waren aufeinanderfolgende Posten unmöglich. Eine Person hat eine Nachricht gesendet und musste warten, bis die andere Person eine einzige Nachricht gesendet hat, bevor sie erneut sprechen konnte. Sehr, sehr begrenzend.Python-Chat-Client-Server-Änderung geht schrecklich falsch

Also fing ich an, es zu fädeln und mit den Sockeln zu experimentieren. Clients stellen einmal eine Verbindung mit dem Server her, geben ihre IP-Adressen ein, erstellen einen Überwachungsthread und stellen anschließend eine Verbindung mit dem Nachrichtenempfänger des Servers her. Alle Beiträge werden an diesen Empfänger gesendet, der durch eine Liste verbundener Clients iteriert und sich mit jedem von ihnen verbindet und die Nachricht sendet (mit dem Namen des Absenders am Anfang; misc-Funktion). (Ich weiß, dass das Öffnen einer neuen Verbindung so oft ineffizient ist, aber ich wollte mit tcp-Verbindungen bleiben, bis ich es funktionierte, und dann zu UDP gehen)

Allerdings begann seltsame Mist passiert. Es genügt zu sagen, dass ich Alpträume von Fehler 91 habe.

Könnte jemand identifizieren, wie dieser Code innerhalb dieser Struktur und Feature-Set funktionsfähig zu machen? (Python-Version 2.6 yey, die unendliche Schleife ignorieren, die nur ein Platzhalter ist)

SERVER CODE:

from socket import * 
from time import time, ctime 
import Queue, threading 

IP = '' 
PORT = 5000 
PORTPlus = 2 
PORTRec = 1000 
ADS = (IP, PORT) 
namelist = [] 
clientlist = [] 



class clientRec(threading.Thread): 
    def __init__(self): 
     threading.Thread.__init__(self) 
     print "I'm this far:", (IP, (PORT + PORTRec)) 
     self.receiver = socket(AF_INET, SOCK_STREAM) 
     self.receiver.bind((IP, PORT + PORTRec)) 
     self.sender = socket(AF_INET, SOCK_STREAM) 
    def run(self): 
     global clientlist, namelist 
     self.receiver.listen(10) 
     connected = True 
     while connected: 
      tcpcli, addr = receiver.accept() 
      message = tcpcli.recv(1024)     # Accept clien't IP for home-dialing 
      for i in range(clientlist.__len__()):    # For each connected client 
       try: 
        sender.connect(clientlist(i))     # connect 
        sender.send(namelist[i] + message)   # and deliver message with sender's name 
        sender.close() 
       except: 
        del clientlist[i], namelist[i] 

print "ADS:", (IP, 5000) 
handle = clientRec() 
tcpsoc = socket(AF_INET, SOCK_STREAM) # Paperwork 
tcpsoc.bind(ADS)      # Bind self to port 
tcpsoc.listen(5)      # Listen on that port0 
handle.start()       # Start thread 

# Main 
while 1: 
    print "Waiting for connection" 
    tcpcli, addr = tcpsoc.accept()  # Accept unknown client 
    print "Connection received; handling..." 
    namelist.append(tcpcli.recv(1024)) # Accept client's name 
    client_IP = tcpcli.recv(1024)  # Accept clien't IP for home-dialing 
    client_port = int(tcpcli.recv(1024))# Accept clien't listening port 
    port_assign = PORT + PORTRec 
    tcpcli.send(str(port_assign))  # Tell the client that port 
    tcpcli.close()      # Close client connection 

    clientlist.append((client_IP, client_port))# Add client to send-list 
    print "Handled." 

tcpsoc.close() 

Client-Code:

#!/usr/bin/env python 

from socket import * 
import threading, cgi, os 

IP = '' 
PORT = 5000 
PORTmy = 100 
ADS = (IP, PORT) 

class iListen(threading.Thread): 
    def __init__(self): 
     threading.Thread.__init__(self) 
     self.receiver = socket(AF_INET, SOCK_STREAM)# Paperwork 
     self.receiver.bind(('', PORT + PORTmy))  # Listen on that port 
     self.receiver.listen(5)      # Listen for posts 
    def run(self): 
     while listening: 
      tcpcli, addr = receiver.accept()  # Accept unknown client 
      message = tcpcli.recv(1024) 
      if message == "/q": 
       listening = False 
      tcpcli.close() 

# Initial CONNECT 
myname = raw_input("Tell me yer name partnah: ") 
tcpsoc = socket(AF_INET, SOCK_STREAM) 
tcpsoc.connect(ADS)      # First Connect 
tcpsoc.send(myname)      # Declare name 
tcpsoc.send(gethostbyname(gethostname()))# Give IP address 
tcpsoc.send(str(PORT + PORTmy))   # Give listening port 
ADS = (IP, int(tcpsoc.recv(1024)))  # Get new connect details 
tcpsoc.close()       # Close old connection 
listen = iListen()      # Create listener thread 
listen.start()       # Start listening 

# RECONNECT 
print ADS 
tcpsoc = socket(AF_INET, SOCK_STREAM) 
tcpsoc.connect(ADS)      # reconnect to new port 
connected = True 

# Main Chat-loop 
while connected: 
    mes = raw_input(">>>") 
    tcpsoc.send(mes) 
    if mes == "/q": 
     tcpsoc.close() 
     connected = False 
     time.sleep(4) 

sys.exit() 
+3

Vielleicht haben Sie Glück und jemand den Code für Sie schreiben, aber ich bezweifle es, partnah. StackOverflow-Fragen müssen etwas fokussierter sein und weniger wie Hausaufgaben aussehen. – msw

+0

UDP für Chat? Haha, gut! PS: Die Einrückung wurde korrigiert ... –

+1

Anstatt zu sagen, dass "komischer Mist begann", möchten Sie vielleicht die Fehler erklären, die Sie im Detail sehen.Versuchen Sie auch, dies auf ein einfacheres Beispiel zu reduzieren, um das Problem besser zu isolieren. Es wird zu Ihrem eigenen Vorteil sein und auch die Frage beantwortbar machen. –

Antwort

0

Ich arbeite an etwas viel wie dieses, aber ich werde stattdessen Textverschlüsselung implementieren. Ich sehe, dass Sie Listen für die Kundenliste verklagen ... aber ich würde sagen, dass es einen besseren Weg gibt, das zu tun. Ich benutze ein Wörterbuch.

Wenn Sie mit Wörterbüchern vertraut sind, überspringen Sie den nächsten Absatz.

Dictionaries können grundsätzlich 2 Variablen verarbeiten und werden mit {} definiert.

>>> stuff = {'a':'hello','b':'world'} 
>>> print stuff['a'] 
hello 
>>> print stuff['a'],stuff['b'] 
hello world 

so diese verwenden, können Sie ein Wörterbuch machen wie { ‚username‘: ‚ipaddr‘} diese Weise können Sie es machen können, so dass beide Benutzernamen und ips alle in einer variabel sind. Wenn Sie das Endprodukt wie mich wollen, werden Sie es so machen, dass der ganze Server die Nachricht wiederholt und sie an alle sendet, die verbunden sind. dann kann der Server einfach durch die Benutzernamen navigieren.

als eine weitere Anmerkung, ich denke, die Tcpsoc.listen (5) ist, wie viele Menschen auf einmal verbunden werden können ... Ich denke, das ist, was ich irgendwo gelesen habe.

Ich habe keine Ahnung, warum Sie diesen Fehler haben würden, aber wenn Sie meinen halbfertigen Code betrachten möchten, sind Sie auch mehr als willkommen. (Ignorieren die Import zufällig wird diese noch nicht verwendet, sondern wird Teil des Verschlüsselungssystems sein)

http://piratepad.net/PwQzdU0bkk

Verwandte Themen