2016-06-15 72 views
3

我目前MYSERVER使用這樣蟒蛇發送TCP/IP數據瞬間

for str in lst: 
    data = str + "\n" 
    self._conn.sendall(data) 

東西現在假設我的列表中有以下兩個字符串發送數據通過TCP/IP它

1-This is statement 1 in list 
2-This is statement 2 in list 

我的客戶正在接收這樣的第2行的一半。

This is statement 1 in list 
    This is 

我想發送line1,然後單獨列表中的第2行。我知道TCP/IP以這種方式工作,它將發送可以發送的全部數據。我想我可以在撥打self._conn.sendall(data)後延遲,但我想知道我有什麼其他選項。我無法對數據的接收者進行更改,我只能對發件人進行更改。到目前爲止,我唯一的選擇是在每次發送後添加延遲。

+1

客戶端需要繼續進行recv調用,直到它擁有一切爲止。我不熟悉Python,所以我不能提供具體的答案。 – kicken

+0

如果您想完全控制每個數據包中發送的內容,還可以選擇使用UDP。 – Aya

回答

5

TCP適用於數據流,而不是單獨的數據包。這就像讀取文件中的數據一樣。發送者將數據放入其發送緩衝區,TCP可以自行決定何時發送它。到達接收應用程序的時間取決於數據何時發送以及網絡條件(通常不可預知)。

TCP交付可以,如果你使用TCP_NODELAY標誌的插座(像socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)作出更可預見,這將導致TCP儘快發送數據到達其緩衝器。但儘管如此,就沒有保證這就是爲什麼基於時間的解決方案至少在某些情況下會破壞的原因

解決方案是將數據流分成塊,有幾種方法可以做到這一點。

  1. 使用固定長度的消息 - 如果所有消息具有固定長度,則r eceiver只需要recv()正確的字節數,處理該消息,然後等待相同數量的字節。

  2. 在每條消息前發送消息的長度。如果你想發送字符串「blah」,編碼爲「0004blah」或類似的東西。接收器將(總是)讀取前四個字節(即0004)來計算要讀取的剩餘字節數。然後它將讀取所需的字節數,處理該消息,然後等待下一個消息。這是一個強大的解決方案,也很容易實現。

  3. 使用分隔符。文本文件中的行被換行符分隔(\n)。同樣,您可以在消息之間添加一個特殊的分隔符字節(或字節)。例如,您可以定義消息始終以美元符號($)結尾。然後,所有接收器必須做的是從字節逐個讀取插槽,直到它收到美元符號。當然,如果採取這種方法,則必須確保消息正文不包含分隔符。

+1

謝謝你清理那個 –

0

TCP基於流而不是單個消息。所以你需要自己解析每條消息的結束點。你的情況中的一個想法是閱讀,直到你得到一個換行符,然後處理該行。請注意,你可能會這樣說的:

This is statement 1 in list 
This is 

然後,你需要檢查,看看是否有一個換行符,工藝路線,然後離開你的緩衝區準備接收其餘部分,像這樣:

This is 
+0

你能舉個例子說明我該怎麼做? –

+0

@JamesFranco:好的:只需將最多1000個字符讀入緩衝區即可。在換行符(''\ n'')上拆分緩衝區。解析第一個N-1塊(這些是完整的行)並保留最後一個塊。然後繼續閱讀,追加到緩衝區並重覆上述步驟。 –

0

TCP有一個本地緩衝區,直到它已滿才發送。您可以強制刷新本地緩衝區,以便在每封郵件後發送它,但當另一方收到這些包時,它們會存儲在另一個本地緩衝區中,並且分隔可能會消失。 TCP是一個流,將其用作流。您必須使用分隔符,並且在收到數據包時,您必須手動分隔消息。如果你想要更多的控制,使用UDP數據包。