2010-07-29 67 views
0

我有一个套接字客户端和一个套接字服务器。如何接收带空数据的套接字消息?

(服务器是蟒蛇,是synchroneous。)

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

与此代码,服务器只是不断的等待,和客户端的不得到任何回报,除非它发送的东西MROE“发”;)

我怎样才能捕捉到空消息?这是否可能?

这是我的服务器代码:

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...) 
+0

这是TCP还是UDP? – 2010-07-29 15:18:37

回答

0

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

+1

客户端的套接字库甚至不会看到它,因为它永远不会到达。 – EJP 2015-08-08 22:29:46

0

假设TCP,你要设计一个协议,表示当你收到一个完整的消息。 send()不保证发送每个字节(检查返回值),并且recv()不保证读取请求的字节数。

设计,其包括一种方法来确定一个完整的消息的协议已被接收。常用的方法是首先发送消息的大小,或者在末尾使用特殊的序列来指示消息已完成。还要注意套接字的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 
-1

如先前回答,的recv()返回 0表示 “断开”,所以不能有一个长度为0的信息。

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

您可以处理这种极端情况,如:

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

来自'recv()'*的*的结果*表示*断开连接。 TCP中的断开*段*是一个包含FIN位的节点。它不一定是零长度。 – EJP 2015-08-08 23:04:09

3
  • 在TCP,有没有这样的事,作为一个空的消息,所以零意味着同行断开。
  • 在UDP中,不存在像对等连接断开这样的事情,所以零意味着一个空的数据报。

正如你描述的一个多线程套接字服务器,它似乎是TCP,在这种情况下你的需求没有意义。您不能通过TCP发送空的消息。你将不得不为所有事情使用叠加协议。

+1

哇,真好。这是一个5岁的问题,我现在无法测试:) – 2015-08-11 15:49:23

0

*假设你正在使用Python的插座模块与TCP/IP前发送数据包:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
sock.connect((ip_in, port_in)) 

你不能用它来发送一个空消息:在TCP/IP发送

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

字符串是空的终止,看起来像这样:

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位数据,不管是否使用或者不是,所以发送一个单一的空字符并不是真正的性能优势。