【问题标题】:Multiple writes get handled as single one多个写入作为单个处理
【发布时间】:2012-04-15 02:54:09
【问题描述】:

我对这段代码有疑问。我正在打开一个套接字,然后用一个 while 循环来监听它。我从 php 脚本发送数据

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

效果很好,但是当我连续发送多个写入时,Python 脚本会将其中一些写入处理为一次写入。

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

我正在寻找一种方法来监听该端口并获得一个接一个的写入。

【问题讨论】:

标签: python sockets network-programming


【解决方案1】:

这不是套接字的工作方式。字节输入和字节输出,但必须有一些其他机制来告诉您消息有多大。如果您发送 50 个字节,然后再发送 75 个字节,然后在套接字的一端发送 20 个字节,然后调用 recv(100),您可以从阻塞套接字中获取 1 到 100 个字节。你负责缓冲recv,直到你有一个完整的消息,你必须定义一个完整的消息是什么。一些选项:

  1. 发送固定长度的消息。
  2. 发送代表消息长度的固定字节数,然后是消息。
  3. 用标记字节分隔消息。

这是一个使用标记字节缓冲接收到的数据的类的示例:

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

【讨论】:

  • 哦,谢谢,这正是我想要的。我对 Python 还是很陌生。
【解决方案2】:

我不认为 unix 套接字是这样工作的。 recv 系统调用可以返回它想要的任何数据,可能会将缓冲区中的消息批处理在一起。 http://linux.die.net/man/2/recv

实现您想要的典型方法是在每条消息之间使用带有分隔符的协议。例如,HTTP 和 SMTP 使用换行符分隔消息的每个部分。

在 python 中,你可以这样使用:

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

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

【讨论】:

  • 这对我来说不太适用。我只会通过连接获得第一次写入。
猜你喜欢
  • 1970-01-01
  • 2019-03-16
  • 2014-02-26
  • 2019-01-31
  • 2014-06-20
  • 1970-01-01
  • 2020-03-31
  • 2022-01-07
  • 2019-07-24
相关资源
最近更新 更多