2015-08-20 53 views
3

我是套接字編程的新手,最近爲它挑選了Python。我有幾個問題,我似乎無法找到明確的答案。Python:通過UDP發送大對象

我正在研究通過UDP發送數據,並寫了一個簡單的python腳本來做到這一點。可以很好地發送小對象(準確地說是小醃製對象),但我應該如何處理太大而不適合一個UDP數據包的對象?

我想過先以字節爲單位調整對象大小。如果對象足夠小以適應UDP數據包,則不會執行任何操作,但如果對象太大,對象將被均勻地分割(如果可能的話)爲許多較小的塊,以便它可以適合多個UDP數據包併發送到客戶端。一旦客戶端收到組塊,客戶端就會將多個UDP數據包重組爲原始狀態。

當試圖實現上述提示時,我立即打開了我的第一堵磚牆。

從我的研究中,似乎沒有任何「有效」的方法來獲取對象的字節大小。這意味着我無法確定一個對象是否太大而不適合UDP數據包。

如果我堅持將大對象發送到客戶端會發生什麼?它會自動分片並在客戶端重新組合,還是客戶端會丟棄數據包?

通過UDP處理大型對象的正確方法是什麼?請記住,大對象可能是1GB大小的文件或25MB大小的字節對象。

在此先感謝。

旁註:

  • 我也明白,UDP數據包可能並不總是爲了和 它因此,我已經實現了對策是 到標籤的序列號發送的UDP數據包給客戶。

  • 我明白,不能保證客戶端將收到所有的UDP數據包。我現在不關心數據包丟失。

  • 我明白,TCP是我正在嘗試做的事情的合適人選,但我的重點是理解UDP以及如何處理現在無法確認客戶端數據包的情況。

  • 我明白泡菜的用法是不安全的。稍後會考慮它。

回答

1

UDP數據包可以大到大約64k。所以如果你想發送一個比這個更大的文件,你可以將自己分成64k的數據包。這是理論上的最大值。我的建議是使用500個字節的小塊。

如果您使用64k數據包,則IP負責數據包的分段和重組。較小的500字節數據包不可能被分割,因爲mtu通常在1500字節左右。如果您使用更大的分段碎片,IP會丟棄它們,如果其中一個碎片丟失的話。

你說得對,使用TCP可能更適合用於類似的東西,甚至像TFTP這樣的現有協議。它實現了每個數據包的加密機制和序列號,就像你一樣。

+0

感謝您的明確解釋。我知道如果文件太大,可以手動將文件分解爲塊,但是對於大於500字節的字節或醃製對象又如何呢?或者對於達到這種大小的python對象來說不太可能?另外,你甚至知道你正在嘗試發送的python對象的大小超過500字節,因爲sys.getsizeof很沒用。 – loftystew

+0

如果你正在傳輸的是一個文件,當然有python中的方法來獲取文件大小和讀取塊。 –

+0

不幸的是,它不是一個文件。我有這樣的想法,我有一個數組存儲順序UDP數據包的數據(例如每5個數據包),然後再將它發送到另一個客戶端。可能有些時候陣列可能會變得太大。不確定這個想法是否可行。 – loftystew

1

處理套接字的大多數應用程序可能會將數據存儲在內存中,直到它全部發送完畢。餿主意!我有一個產品應用程序必須通過網絡發送非常大的文件,並在過去使用分塊方法。我剛剛在Python中重寫了一些我的代碼(binfileio)。在我的應用程序中,我將夾頭文件發送到一個保留的文件夾,一旦所有分塊的文件都塞在牀上,我重新組裝它們。我從來不信任通過電線發送大文件,隨時都可以刪除。希望這可以幫助。

+0

大發送數據!我會將此視爲發送大文件的起點。非常感謝。 – loftystew

0

Pytho 3.0

代碼通過UDP通信

import socket 
UDP_IP = "127.0.0.1" 
UDP_PORT = 5005 
MESSAGE = "Hello, World!" 
print("UDP target IP:",UDP_IP) 
print("UDP target port:",UDP_PORT) 
print("message:",MESSAGE) 
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
sock.sendto(bytes(MESSAGE, "utf-8"), (UDP_IP, UDP_PORT))