2012-03-31 13 views
2

Ich habe ein Problem hier mit diesem Code. Ich öffne eine Steckdose und höre dann mit einer While-Schleife zu. Ich sende Daten von einem PHP-Skript mitMehrere Schreibvorgänge werden als einzelne behandelt

socket_write($sock, $test, $len); 

Es funktioniert sehr gut, aber wenn ich mehrere schreibt in einer Reihe senden, der Python-Skript einige des Schreib behandelt als nur einen Schreib.

import socket 

HOST = 'localhost' # the host 
PORT = 12126 # the port 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.bind((HOST, PORT)) 
while 1: 
    s.listen(0) 
    conn, addr = s.accept() 
    print 'Connected by', addr 
    while 1: 
     data = conn.recv(1024) 
     if not data: break 
conn.close() 

Ich bin auf der Suche nach einer Möglichkeit, diesen Port zu hören und einen nach dem anderen zu bekommen.

+0

puffert PHP die Schreibvorgänge? http://us.php.net/manual/en/function.fflush.php –

+0

Ja, ich kann sie im Python-Programm drucken und sehen. –

Antwort

4

, dass die Arbeit nicht so, wie Steckdosen ist. Bytes gehen hinein und Bytes kommen heraus, aber es muss einen anderen Mechanismus geben, der Ihnen sagt, wie groß eine Nachricht ist. Wenn Sie 50 Bytes, dann weitere 75 Bytes, dann 20 Bytes an einem Ende eines Sockets senden und dann recv (100) anrufen, können Sie zwischen 1 und 100 Bytes von einem blockierenden Socket bekommen. Sie sind für das Puffern von Recvs zuständig, bis Sie eine vollständige Nachricht erhalten haben und Sie definieren müssen, was eine vollständige Nachricht ist. Einige Optionen:

  1. Nachrichten mit fester Länge senden.
  2. Senden Sie eine feste Anzahl von Bytes, die die Länge der Nachricht darstellen, dann die Nachricht.
  3. Separate Nachrichten mit einem Sentinel-Byte.

Hier ist ein Beispiel einer Klasse empfangenen Daten zu puffern ein Sentinel-Byte mit:

import socket 

class Client(object): 

    def __init__(self): 
     self.buffer = '' 
     self.sock = None 

    def connect(self,address): 
     self.buffer = '' 
     self.sock = socket.socket() 
     self.sock.connect(address) 

    def get_msg(self): 
     '''Append raw data to buffer until sentinel is found, 
      then strip off the message, leaving the remainder 
      in the buffer. 
     ''' 
     while not '\n' in self.buffer: 
      data = self.sock.recv(4096) 
      if not data: 
       return '' 
      self.buffer += data 
     sentinel = self.buffer.index('\n') + 1 
     msg,self.buffer = self.buffer[:sentinel],self.buffer[sentinel:] 
     return msg 

    def close(self): 
     self.sock.close() 

if __name__ == '__main__': 
    c = Client() 
    c.connect((HOST,PORT)) 
    while True: 
     msg = c.get_msg() 
     if not msg: 
      break 
     print repr(msg) 
    c.close() 
+0

Aw, danke das ist, was ich gesucht habe. Ich bin immer noch ziemlich neu in Python. –

1

Ich glaube nicht, dass so Unix-Sockets funktionieren. Der Systemaufruf recv kann beliebig viele Daten zurückgeben und möglicherweise Nachrichten im Puffer zusammenbuchen. http://linux.die.net/man/2/recv

Der typische Weg, um zu erreichen, was Sie wollen, ist ein Protokoll mit Trennzeichen zwischen jeder Nachricht zu verwenden. HTTP und SMTP verwenden beispielsweise Zeilenumbrüche, um jeden Teil einer Nachricht zu trennen.

In Python, Sie so etwas wie diese verwenden:

for message in data.split('\n'): 
    do_stuff(message) 

http://docs.python.org/howto/sockets.html

+0

Das funktioniert nicht ganz für mich. Ich bekomme nur den ersten Schreibvorgang über eine Verbindung. –

Verwandte Themen