2014-11-03 58 views
0

我正在創建一個小腳本,以使用Python 3套接字庫將呼叫記錄發送到服務器。Python socket.sendall發送顯然是任意長度

每條記錄​​的長度都是109個字節。

當我通過套接字發送器循環並觀察接收端以及wireshark時,發現有些數據包太大而無法正確。 Wireshark顯示具有正確數據的數據包長度爲170。有一些數據包長度超過1500。

有時,接收端會拒絕2個長度爲59和50的數據包(合計爲1個完整數據包)。

有沒有辦法讓這個工作更可靠?

以下是我正在使用的方法。

def connect_to_collector(iterator_obj, host, port, rate, count): 

if count == None: 
    count = len(iterator_obj.mylist) 
delay = 3600/int(rate) 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.connect((host, int(port))) 
print ('\n[+] Connected to {} on port {}'.format(host, port)) 

start = timer() 
i = 0 
for record in iterator_obj: 

    if i < count: 
    try: 
     if len(record) is not length: 
     print ('the length was ', length) 
     s.sendall(record) 
     time.sleep(delay) 
     i += 1 

    except: 
     e = sys.exc_info() 
     print ('SEND ERROR OCCURRED ', e) 
     print ('\n[+] Sent {} to {} on port {} in {:.4f} seconds'.format(i, host, port, timer() - start)) 
     sys.exit() 

    if verbose: 
     print ('Sending : |{:' '<150}| record number |{}|'.format(record, i)) 
    if i >= count: 
    break  
# Clean up 

print ('\n[+] Sent {} to {} on port {} in {:.4f} seconds'.format(count, host, port, timer() - start)) 

s.close() 

編輯:有一個在

for record in iterator_obj: 

    if i < count: 
    try: 
     if len(record) is not length: 
     print ('the length was ', length) 
     s.sendall(record) 

錯誤的迭代器內的同時,會偶然sendall()被調用了同一條記錄多次。

我刪除了那個循環。

回答

0

S = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

有沒有辦法得到這個更可靠地工作?

您在此處使用TCP,TCP是流協議,而不是數據報(數據包)協議。這意味着整個連接被視爲單個數據流,而TCP堆棧可以自由優化以優化傳輸,例如一起發送一些數據或分割一些其他數據。如果你期待每一個recv匹配一個發送你做錯了。

如果你想要一個數據報協議使用UDP。但在這種情況下,您必須處理丟失的數據包和數據包重新排序或複製自己。像SCTP這樣的協議是一種像UDP這樣的數據報協議,但具有TCP的可靠性,但它們可能不是在任何地方得到普遍支持,並且您可能會通過防火牆使用它。

+0

這是有道理的。另外,我只是想指出後代的緣故,我的代碼中有一個錯誤導致它發送重複。將在更正中編輯。 – Balrizangor 2014-11-07 06:21:45