Hallo zusammen,
ich will einen Client machen der von einem Server Daten bekommt.
Die Antwort kann variabel lang sein daher weis ich nicht wir groß der buffer sein muss. Kann man das irgenwie variabel gestalten ?
Thonix
Wie lange muss der Buffer in socket.recv(buffer) sein
- Rebecca
- User
- Beiträge: 1662
- Registriert: Freitag 3. Februar 2006, 12:28
- Wohnort: DN, Heimat: HB
- Kontaktdaten:
Die Buffergroesse gibt nur an, vieviel auf einmal gelesen werden kann. Ist deine Nachricht laenger, kannst du nicht alles auf einmal lesen, aber der Rest geht nicht verloren und wird beim naechsten recv gelesen.
- Rebecca
- User
- Beiträge: 1662
- Registriert: Freitag 3. Februar 2006, 12:28
- Wohnort: DN, Heimat: HB
- Kontaktdaten:
Wovon reden wir denn? Bei Sockets bekommt man keinen Timeout, die blockieren einfach bis etwas da ist oder der Socket geschlossen wird (es sei denn, du verwendest select).
Wie auch immer, du musst mit der Gegenseite ein "Nachricht ist zuende"-Signal vereinbaren, eine moeglichst eindeutige Zeichenabfolge ("===ENDOFMESSAGE===" oder sowas), wenn du so low-level arbeitest.
Wie auch immer, du musst mit der Gegenseite ein "Nachricht ist zuende"-Signal vereinbaren, eine moeglichst eindeutige Zeichenabfolge ("===ENDOFMESSAGE===" oder sowas), wenn du so low-level arbeitest.
Wenn der Sender die Verbindung schliesst, dann wird eine leere Zeichenkette zurückgegeben. Wenn Du noch mehr über die Verbindung schicken willst, dann musst Du entweder am Anfang übertragen wieviele die Daten empfangen werden müssen oder ein Endkennzeichen/Trennzeichen nach einem "Paket" einbauen und mindestens soviel lesen bis die Markierung im Datenstrom auftaucht.
In dem Zusammenhang lohnt sich vielleicht auch ein Blick in die Module `asyncore` und `asynchat`.
In dem Zusammenhang lohnt sich vielleicht auch ein Blick in die Module `asyncore` und `asynchat`.
evtl. hilft auch ein paar Hinweise....
Erstens, es ist selten möglich, eine echte Client-Server Kommunikation nur auf dem Basis vom socket recv() und send() direkt zu machen, aus verschiedene Grunde. Man muss eine gewisse Protocol etablieren. Zum Beispiel ein Client würde Kontakt mit dem Server aufnehemen, warten auf Bestätigung, sende seine "Paketen" und zum Schluss auch den Server Bescheid geben, wenn er "ausloggt".
In diesem Beispiel, Funktionen wie isServerReady() und sendPacket() sind eigene Code, die auf socket.recv() und socket.send() basiert sind. Hier ein Beispiel für sendPacket()
Die Länge der Daten wird vorne weg geschickt, so kann der Server mit einer eigenen getPacket() Funktion "wissen" wie viele Daten zu erwarten/lesen sind.
Funktion isServerReady() wartet bis eine bestimmte Meldung vom Server zurück kommt....das gibt den Server einige Zeit um, z.B. einen neuen Thread aufzubauen.
Die letzte "DONE" Paket sorgt dafür, dass der Server sein Thread auch wegraumen/beenden kann und tote Threads auf der Server-Seite nicht entstehen.
Also, eine klare Protokol muss festgeleget werden. Wenn man selbst sowohl der Client und Server schreibt, ist das meistens kein Problem. Muss man ein Client schreiben, der mit einen Fremden Server kommunizieren muss, dann muss man erst der Server-Protocol kennenlernen.
Letzlich dann implementiert man getPacket() und sendPacket() Funktionen (wie auch immer sie heissen am Ende) um MINDESTENS die Länge von den Daten zu vermitteln. Eine einfache send.... steht oben, die entsprechende get... würde etwa wie folgt aussehen.
Sehr einfach hier gestaltet....es gibt etliche Varianten und Möglichkeiten hier. Manche Client/Server schicken komplexe "Semaphors" hin und her und Datenlänge und Daten getrennt, usw.
Also, eine richtige "Kommunikation" aufbauen, darunter die recv() und send() vom socket Module verwenden.
Erstens, es ist selten möglich, eine echte Client-Server Kommunikation nur auf dem Basis vom socket recv() und send() direkt zu machen, aus verschiedene Grunde. Man muss eine gewisse Protocol etablieren. Zum Beispiel ein Client würde Kontakt mit dem Server aufnehemen, warten auf Bestätigung, sende seine "Paketen" und zum Schluss auch den Server Bescheid geben, wenn er "ausloggt".
Code: Alles auswählen
sockobj = socket( AF_INET, SOCK_STREAM )
sockobj.settimeout(5.0)
sockobj.connect( (serverHost, serverPort) )
# Wait for server to indicate it is ready
isServerReady( sockobj )
# Send our request
for line in message:
sendPacket( sockobj, line )
....weitere Kommunikation
# Tell the server we're closing down
sendPacket( sockobj, "DONE" )
sockobj.close()
Code: Alles auswählen
def sendPacket( sockobj, data ):
iLen = len(data)
sockobj.send( str(iLen) )
sockobj.send( ":" )
sockobj.send( data )
Funktion isServerReady() wartet bis eine bestimmte Meldung vom Server zurück kommt....das gibt den Server einige Zeit um, z.B. einen neuen Thread aufzubauen.
Die letzte "DONE" Paket sorgt dafür, dass der Server sein Thread auch wegraumen/beenden kann und tote Threads auf der Server-Seite nicht entstehen.
Also, eine klare Protokol muss festgeleget werden. Wenn man selbst sowohl der Client und Server schreibt, ist das meistens kein Problem. Muss man ein Client schreiben, der mit einen Fremden Server kommunizieren muss, dann muss man erst der Server-Protocol kennenlernen.
Letzlich dann implementiert man getPacket() und sendPacket() Funktionen (wie auch immer sie heissen am Ende) um MINDESTENS die Länge von den Daten zu vermitteln. Eine einfache send.... steht oben, die entsprechende get... würde etwa wie folgt aussehen.
Code: Alles auswählen
def getPacket( sockobj ):
length = ''
while 1:
nextChar = sockobj.recv(1)
if nextChar == ':':
break
else:
length = length + nextChar
expect = int( length )
data = sockobj.recv( expect )
return data
Also, eine richtige "Kommunikation" aufbauen, darunter die recv() und send() vom socket Module verwenden.