2012-05-24 56 views
2

我已經在UDP下創建了一個echo服務器,並且正在處理一個客戶端,該客戶端將給定文件拆分爲數據包並將其傳輸到服務器,然後服務器返回數據包由客戶重新組裝。如何使用UDP_CORK正確設置UDP套接字

發送單個數據包工作得很好。但是,我試圖使用UDP_CORK套接字選項在一個數據包中儘可能多地傳輸文件的各個部分。我用下面的代碼工作:

#define LINE_SIZE 80 

... 
// s = socket descriptor. 
... 

int one = 1; 
int zero = 0; 

setsockopt(s, IPPROTO_UDP, UDP_CORK, &one, sizeof(one)); // cork 

/* Send to server, receive from server, write to new file. */ 

FILE *orig, *copy; 
char line[LINE_SIZE]; 

if ((orig = fopen(input + 3, "rb")) == NULL) // original file 
    print_error(input); 

if ((copy = fopen(filename, "wb")) == NULL) // copy of file 
    print_error("fopen"); 

while (fread(line, sizeof(char), LINE_SIZE, orig) > 0) { 
    if (sendto(s, line, LINE_SIZE, 0, (struct sockaddr *)&srv, len) == -1) 
    print_error("sendto"); 
} 

setsockopt(s, IPPROTO_UDP, UDP_CORK, &zero, sizeof(zero)); // uncork 

if (recvfrom(s, line, LINE_SIZE, 0, (struct sockaddr *)&srv, &len) == -1) 
    print_error("recvfrom"); 

fwrite(line, sizeof(char), LINE_SIZE, copy); 

服務器表明,它只是接受一個「正常大小的」數據包,而不是塞住的包,我想。因此,它只是發回這個正常的數據包,通過recvfrom()調用由客戶端接收。

我不確定是否正確設置了UDP_CORK。第二個參數是否正確?我並不瞭解第二種選擇的真正含義,因爲手冊頁並不完全清楚。我也可能誤解軟木塞的工作原理。

有幾件事情需要注意:

  • 我認爲自己是一箇中間層次的程序員,但我很少有網絡編程經驗。
  • 我意識到UDP並不是傳輸文件的最佳選擇。這最終將適應我正在幫助開發的不同協議。

謝謝!

回答

1

該文件有多大?你知道UDP數據報的大小限制爲64K,對吧?然後超過1472字節(1500字節的可用以太網有效負載少於20字節的IP報頭,少於8字節的UDP報頭)是IP分段的。

然後你永遠不會檢查setsockopt(2)的返回值。你怎麼知道它成功了?

然後fread(3)告訴你它讀了多少,但你仍然嘗試發送LINE_SIZE字節。這是錯誤的。

+0

這是非常正確的。我沒有考慮大小,我嘗試的文件沒有很多描述性字節,直到1472門檻之後。並感謝您指出我的其他失誤。但是,當數據報是IP分段的時候,其他的不應該發送到一個或多個數據包中嗎?我只接收第一個。 – Cody

+0

內核可能會拒絕將MTU的大小壓縮到一個數據報中,儘管我不確定它的大小,但事實上,您會收到第一個塊。有了碎片,你不會得到數據報的一部分 - 你可以得到整個事情或沒有。 –