Rhytmus probleme

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Mohammed
User
Beiträge: 8
Registriert: Samstag 26. Februar 2011, 21:13

hi, bin neu im Forum und habe folgendes Problem:
Server:

Code: Alles auswählen

import socket 
import select

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
server.bind(("", 60000)) 
server.listen(1)

clients = []

try: 
    while True: 
        lesen, schreiben, oob = select.select([server] + clients, 
                                              [], [])

        for sock in lesen: 
            if sock is server: 
                client, addr = server.accept() 
                clients.append(client)
                b="+++ Client %s verbunden" % addr[0]
                for a in clients:
                    a.send(b)
            else: 
                nachricht = sock.recv(1024) 
                ip = sock.getpeername()[0] 
                if nachricht: 
                    for d in clients:
                        if d is sock:
                            continue
                        e="[%s] %s" % (ip, nachricht)
                        d.send(e) 
                else: 
                    for f in clients:
                        g="+++ Verbindung zu %s beendet" % ip
                        f.send(g)
                    sock.close() 
                    clients.remove(sock) 
finally: 
    for c in clients: 
        c.close() 
    server.close()
Client

Code: Alles auswählen

import socket
import select

ip = "127.0.0.1"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.connect((ip, 60000))

try: 
    while True:
        lesen, schreiben, oob=select.select([s],[],[])
        if lesen:
            a=s.recv(1024)
            print a
        nachricht = raw_input("Nachricht: ") 
        s.send(nachricht)
finally: 
    s.close()
Diese beiden Programme harmonieren nicht miteinander :?
Das Problem ist, das der Clien nicht im rythmus schickt und man manchmal warten muss bis der andere was schickt, ich hab absolut keinen plan was ich da machen kann.
Bitte brauche unbedingt hilfe :roll:

Ps: Cooles Forum :mrgreen:
Zuletzt geändert von Anonymous am Freitag 4. März 2011, 17:33, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
lg Mohammed
BlackJack

@Mohammed: Mach Dir mal Gedanken über den Programmablauf im Client. Der blockiert ja beim `raw_input()` -- das heisst solange er auf die Eingabe vom Benutzer wartet, kann er nichts empfangen und ausgeben. Schlimmer noch -- an der Stelle könnte er den Server blockieren wenn der mehr sendet als in die Pufferspeicher auf beiden Seiten passt. Ein robuster Server müsste an der Stelle also auch bei den `send()`\s mittels `select()` dafür sorgen, dass das ohne zu blockieren funktioniert. Dann müsste die Programmstruktur vom Server aber auch ein wenig komplexer werden, zum Beispiel mit Nachrichten-Warteschlangen pro Client, denn es ist ja nicht garantiert, dass die Clients die Nachrichten alle gleich schnell empfangen können.

`a`, `b`, `d`, `e`, `f`, und `g` als Namen sind nicht hilfreich wenn man verstehen will, was ein Programm macht.
Mohammed
User
Beiträge: 8
Registriert: Samstag 26. Februar 2011, 21:13

@BlackJack; danke, für diese antwort bin ich dankbar :mrgreen:
Das mit den input, wieso bin ich nicht darauft gekommen :roll:
Und bin der namensverteilung: das war nur ein test, das verbesser ich noch xD
Jetzt zu den maximal Puffer: hättets du eine idee wie ich das machen könnte?

Code: Alles auswählen

sock.recv(1024) 
meinst du jetzt?
lg Mohammed
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Offtopic: Das Python-Beispiel soll ja offenbar ein Chat sein. Rohe Socket-Programmierung in Python ist IMHO recht umständlich. Zum Vergleich dazu mal das ganze in JavaScript für Node.js. Der Server merkt sich alle Sockets, wenn auf einem davon Daten ankommen, werden sie an alle verteilt. Wird ein Socket geschlossen, wird er wieder aus dem clients-Array entfernt. Da JavaScript kein "remove" für Arrays kennt, sieht dies leider etwas komplizierter (splice/indexOf) aus.

Code: Alles auswählen

clients = []
require('net').createServer(function(socket){
  clients.push(socket)
  socket.on('data', function(data){
    for (var i in clients){
      if (clients[i].writable) clients[i].write(data)
    }
  })
  socket.on('end', function(){
    clients.splice(clients.indexOf(socket), 1)
  }
}).listen(3000)
Dagegen kann man sich mit "telnet" verbinden oder aber folgenden Client benutzen:

Code: Alles auswählen

socket = require('net').createConnection(3000)
socket.on('data', function(data){
  process.stdout.write(data) 
})
process.stdin.resume()
process.stdin.on('data', function(data){
  socket.write(data);
})
Node könnte gerne noch das Äquivalent zu raw_input() haben. Die letzten 4 Zeilen implementieren dies. Ich muss stdin aktivieren und kann dann darauf warten, dass jemand etwas eingibt, was ich dann in mein offenes Socket schreibe. Kommt in meinem Socket etwas an, gebe ich es auf der Konsole aus.

Warum kann es das selbe einfache API nicht auch in Python geben?

Stefan
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Man könnte sys.stdin auf non-blocking setzen, erfordert aber dass man sich mit ioctl und termios auseinandersetzt und ich hab keine Ahnung wie man dies unter Windows anstellt oder ob es da überhaupt geht.

raw_input kann man dann auch nicht mehr nutzen.

Wahrscheinlich ist es einfacher Threads zu nutzen und/oder statt socket gleich ein Framework wie Twisted oder asynchia(?).
BlackJack

@sma: In Python kann man halt aus syntaktischen Gründen nicht so einfach anonyme Funktionen definieren. Und falls es Dir um das ereignisbasierte Modell ging: Dafür gibt es auch in Python Rahmenwerke die das machen.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

sma hat geschrieben:Warum kann es das selbe einfache API nicht auch in Python geben?
Anonyme Funktionen und Blöcke fehlen. So eine "einfache" API wäre in Python grausam.

Eine sinnvolle Alternative wäre etwas basierend auf eventlet.
Antworten