如何接收带有空数据的套接字消息?

时间:2010-07-29 14:14:31

标签: python sockets

我有一个套接字客户端和一个套接字服务器。

(服务器在python中,并且是同步的。)

有时客户端会发送一个空字符串。我需要确定这种情况,并返回一个回复。

使用此代码,服务器只是等待,并且客户端没有得到任何回报,除非它发送一些东西“胖”;)

我如何捕捉空信息?是不是很有可能?

这是我的服务器代码:

import SocketServer

def multi_threaded_socket_server():

    class MyRequestHandler(SocketServer.BaseRequestHandler):
        def handle(self):
            while True:
                print 'waiting for client calls...'
                received = self.request.recv( PACKET_SIZE )
                (handle request... )

5 个答案:

答案 0 :(得分:5)

  • 在TCP中,没有空消息,因此零表示对等断开。
  • 在UDP中,没有对等断开连接,因此零表示空数据报。

在描述多线程套接字服务器时,它似乎是TCP,在这种情况下,您的要求没有意义。您无法通过TCP发送空消息。你必须为所有事情使用叠加协议。

答案 1 :(得分:0)

如果空字符串表示0字节,则客户端侧的套接字库可能会忽略它,因为具有0个数据字节的数据包是断开连接数据包。

答案 2 :(得分:0)

假设TCP,您必须设计一个协议,指示您何时收到完整的消息。 send()不保证发送每个字节(检查返回值)和recv()不保证读取请求的字节数。

设计一种协议,其中包括确定已收到完整消息的方法。常见的方法是首先发送消息的大小,或者在结尾处使用特殊的序列来指示消息已完成。另请注意socket的sendall()方法发送消息的所有字节。

示例:

sendall('\x05Hello')  # length first
sendall('Hello\x00')  # nul-termination

对于接收,缓冲区recv()调用,直到出现完整的消息。

接收算法(非工作代码):

class Handler:

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

  def handler(self):
    while True:
      msg = self.get_msg()
      if not msg: break
      process msg

  def get_msg(self):
    if complete message not at the beginning of buffer:
      chunk = recv(1000)
      if not chunk: return '' # socket closed
      buffer += chunk
    remove message from beginning of buffer...update buffer
    return message

答案 3 :(得分:-1)

如前所述, recv()返回0意味着“断开连接”,因此您不能拥有0长度的消息。

但是,如果您只将它看作一个字符串,如果实际收到的是一个以'\ 0'字符开头的数据包,则可以获得似乎为空的TCP消息。

你可以处理这个角落案例,如:

received = self.request.recv( PACKET_SIZE )
if received[0]=='\x00':
    <handle empty packet>

答案 4 :(得分:-1)

*假设您使用TCP / IP ex:

发送带有python套接字模块的数据包
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip_in, port_in))

您不能用来发送空消息:

sock.sendall(bytes("", 'ascii'))

使用TCP / IP发送的字符串为空终止,如下所示:

IP packing | TCP packing | string | null ascii character (0x00 in hex)

因此发送“”将导致:

IP packing | TCP packing | 0x00

TCP服务器将其解释为断开连接,处理程序将不会为请求提供服务。

要发送服务器将处理的“空消息”,请使用以下内容:

sock.sendall(bytes("\00", 'ascii'))

发送一个看起来像的数据包:

IP packing | TCP packing | 0x00 | 0x00

并且处理看起来像:

data = str(self.request.recv(1024), 'ascii')
# data = ""

尽管所有tcp数据包都使用32位数据而不管它是否被使用,因此发送单个空字符并不会对性能产生太大影响。