Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
135 views
in Technique[技术] by (71.8m points)

python - Multiple writes get handled as single one

I have a problem here with this code. I'm opening a socket, then listening to it with a while loop. I send data from a php script with

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

It works very well, but when I send several writes in a row, the Python script handles some of the writes as just one write.

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()

I'm looking for a way to listen to that port and get one write after another.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

That's not the way sockets work. Bytes go in and bytes come out, but there has to be some other mechanism to tell you how big a message is. If you send 50 bytes, then another 75 bytes, then 20 bytes on one end of a socket, and then call recv(100), you could get anywhere from 1 to 100 bytes from a blocking socket. You are responsible for buffering recv's until you have a complete message, and you have to define what a complete message is. Some options:

  1. Send fixed length messages.
  2. Send a fixed number of bytes representing the length of the message, then the message.
  3. Separate messages with a sentinel byte.

Here's an example of a class to buffer received data using a sentinel byte:

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 '
' in self.buffer:
            data = self.sock.recv(4096)
            if not data:
                return ''
            self.buffer += data
        sentinel = self.buffer.index('
') + 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()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...