Server-Client-Programm mit socket.makefile()

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
fr34k
User
Beiträge: 11
Registriert: Donnerstag 30. Oktober 2008, 13:19

hallo,
ich arbeite zur zeit an einem server-client-programm, bei dem ich die daten mit socket.makefile() und dem pickle-modul verschicke, da ich nicht nur strings, sondern auch objekte eigener klassen verschicken möchte.
zunächst hat alles wunderbar funktioniert, doch dann bin ich auf folgendes problem gestoßen:
wenn der server erneut daten sendet, bevor der client das vorherige datenpaket abgearbeitet und bereit für neue daten ist, dann bleiben diese neuen daten irgendwo auf der strecke...jedenfalls bleibt der client dann beim empfangsbefehl hängen, bis der server wieder etwas sendet. im umgekehrten fall, also wenn der client an den server sendet, tritt genau das gleiche problem auf.
ich habe das ganze mal auf das wesentliche reduziert...ich denke man versteht dann besser was ich meine:

Code: Alles auswählen

###funcs.py
import pickle

address = ('localhost', 8000)

def send(data, socket):
    f = socket.makefile()
    pickle.dump(data, f)
    f.close()

def receive(socket):
    f = socket.makefile()
    data = pickle.load(f)
    f.close()
    return data


###server.py
import socket, time
from funcs import *

serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(address)  #address seht in funcs
serversocket.listen(5)

print 'server'

clientsocket, clientaddress = serversocket.accept()

#empfangen
time.sleep(1)
data = receive(clientsocket)
print data
data = receive(clientsocket)
print data

raw_input('')


###client.py
import socket, time
from funcs import *

clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.connect(address)   #address seht in funcs

print 'client'

#senden
send(1, clientsocket)
#time.sleep(1.5)             #den Befehl auskommentieren zum testen
send(2, clientsocket)

raw_input('')
beim ausführen erscheint in der ausgabe des servers nur die 1 vom ersten senden-befehl. dann bleibt das programm stehen...
nehme ich die kommentierte zeile im client raus (time.sleep(1.5)), sendet der client, wenn der server bereits auf neue daten wartet und auch die 2 erscheint in der ausgabe.

ich habe bereits versucht, an die funktionen send() und receive() statt des socket die socketfile zu übergeben, und die datei nach dem senden/empfangen demzufolge nicht zu schließen...dann kommt allerdings gar nix mehr an...

ich hoffe es ist verständlich was das problem ist und jemand kann mir weiterhelfen.

schonmal thx im voraus
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Sollte man makefile() nicht besser mit mode='rb' bzw. mode='wb' aufrufen?
MfG
HWK
fr34k
User
Beiträge: 11
Registriert: Donnerstag 30. Oktober 2008, 13:19

kann gut möglich sein...doch leider ändert das nichts an meinem problem :(
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Hast Du Dir das so vorgestellt?
Server

Code: Alles auswählen

import pickle, socket

address = ('localhost', 8000)

serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(address)
serversocket.listen(5)

print 'server'

clientsocket, clientaddress = serversocket.accept()

f = clientsocket.makefile(mode='rb')
data = pickle.load(f)
print data
data = pickle.load(f)
print data
f.close()

raw_input('')
Client

Code: Alles auswählen

import pickle, socket

address = ('localhost', 8000)

clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.connect(address)

print 'client'

f = clientsocket.makefile(mode='wb')
pickle.dump(1, f)
pickle.dump(2, f)
f.close()

raw_input('')
MfG
HWK
fr34k
User
Beiträge: 11
Registriert: Donnerstag 30. Oktober 2008, 13:19

naja nich ganz...
dein vorschlag funktioniert nur dann wenn ich weiß ob ich als nächstes was sende oder empfange...das weiß ich allerdings nicht...ich will damit ja nen komplettes server-client-programm schreiben
also muss ich muss ich ständig die socketfile wieder schließen
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

fr34k hat geschrieben:also muss ich muss ich ständig die socketfile wieder schließen
Warum? Du kannst es ja geöffnet lassen.
MfG
HWK
fr34k
User
Beiträge: 11
Registriert: Donnerstag 30. Oktober 2008, 13:19

wenn ich sie geöffnet lasse, kann ich auf der anderen seite nix mehr empfangen...ich muss erst im client f.close() aufrufen, bevor ich im server was empfangen kann...vorher reagiert er jedenfalls nicht..deswegen bin ich darauf gekommen jedesmal socket.makefile() aufzurufen und anschließend die socketfile hinterher wieder zu schließen...und das hat mich zu dem beschriebenem problem geführt...
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Stell mal das Buffering von Makefile aus.

Und bist du dir sicher das du Pickles versenden willst?
Dir ist bewusst das mit Pickles beliebiger Code ausgeführt werden kann und das es fertige Lösungen wie XML und JSON RPC gibt?
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
fr34k
User
Beiträge: 11
Registriert: Donnerstag 30. Oktober 2008, 13:19

danke...ohne buffering scheint alles zu funktionieren

also auf pickle bin ich nur gekommen, weil man mir gesagt hat, dass man damit beliebige objekte verschicken kann...
wie sowas mit xml geht weiß ich nich...und JSON RPC hab ich bis jetz noch nix gehört...aber ich kanns mir ja mal anschauen...nur wenns zu komplex wird lass ich das lieber erst einmal...

kannst du mir zufällig ne gute doku dafür sagen?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

fr34k hat geschrieben:kannst du mir zufällig ne gute doku dafür sagen?
XML-RPC ist in der Stdlib dokumentiert.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten