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

3 投票
5 回答
16744 浏览
提问于 2025-04-16 02:01

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

(服务器是用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

如果空字符串表示0字节,那么客户端的套接字库可能会忽略它,因为一个数据字节为0的包被认为是断开连接的信号。

2

假设你在使用TCP协议,你需要设计一种协议来表示你已经收到了完整的信息。send()这个函数并不能保证每个字节都会被发送出去(你需要检查返回值),而recv()这个函数也不能保证能读取你请求的字节数。在TCP的recv()情况下,如果接收到零字节,这表示连接已经关闭,所以没有办法发送一个空的信息而不带一些额外的信息(这些额外的信息是用来描述数据的)。

因此,你需要设计一个协议,里面要有一种方法来判断是否收到了完整的信息。常见的方法是先发送信息的大小,或者在信息的末尾使用一个特殊的序列来表示信息已经完整。此外,要注意socket的sendall()方法会确保发送所有字节的信息。

示例:

sendall('\x05Hello')  # length first
sendall('Hello\x00')  # nul-termination
sendall('\x00')       # length first, empty message
sendall('\x00')       # empty string, 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
10
  • 在TCP协议中,没有“空消息”这个概念,所以发送0就意味着对方断开了连接。
  • 在UDP协议中,没有“对方断开连接”这个说法,所以发送0就表示发送了一个空的数据包。

你提到的是一个多线程的套接字服务器,这听起来像是TCP协议。在这种情况下,你的要求就不太合理了。因为在TCP中,你不能发送空消息。如果想要实现这个功能,你就得使用一种额外的协议来处理所有的内容。

撰写回答