2010-07-29 46 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位數據,不管是否使用或者不是,所以發送一個單一的空字符並不是真正的性能優勢。