2012-08-29 54 views
0

1:服務器文件大小複製到緩衝器併發送它:Ç套接字發送和接收int,而不是字符緩衝區

snprintf(t_buf, 255, "%" PRIu32, fsize); 
    if(send(f_sockd, t_buf, sizeof(t_buf), 0) < 0){ 
    perror("error on sending file size\n"); 
    onexit(f_sockd, m_sockd, 0, 2); 
    } 

2:客戶端接收的文件大小,放入FSIZE :

if(recv(f_sockd, t_buf, sizeof(t_buf), 0) < 0){ 
    perror("error on receiving file size"); 
    onexit(f_sockd, 0 ,0 ,1); 
    } 
    fsize = atoi(t_buf); 

-----------------上面的代碼使我的程序完美工作!

的問題發生,如果我寫這樣的代碼,而不是以前的一個:
1:服務器發送FSIZE:

if(send(f_sockd, &fsize, sizeof(fsize), 0) < 0){ 
    perror("error on sending file size\n"); 
    onexit(f_sockd, m_sockd, 0, 2); 
    } 

2,客戶端接收FSIZE:

if(recv(f_sockd, &fsize, sizeof(fsize), 0) < 0){ 
    perror("error on receiving file size"); 
    onexit(f_sockd, 0, 0, 1); 
    } 

uint32_t fsize;char t_buf[256];
問題是,使用第一種方法都可以工作,但使用第二種方法,客戶端不會收到所有文件,只能收到一小部分文件。這段代碼有什麼問題?
謝謝!

+0

[處理從recv的部分回報(c)中TCP](可能重複http://stackoverflow.com/questions/1386142/handling-partial-return-from-recv-tcp-in-c) –

+0

看起來不像它,上面的代碼只是錯誤的;-)。 –

+0

客戶端和服務器在同一臺機器上嗎?只是它的一部分意味着什麼? – hmjd

回答

0

很難說,沒有更多的數據。

可能是endianness。你應該打印出fsize的值。

也可以從recv()部分返回,如評論中所述。

+0

小端,我在同一臺機器上運行服務器和客戶端! – polslinux

1

recv(2)不一定填寫完整的輸出緩衝區 - 這可能取決於有多少數據返回較少的字節可用:

的接聽電話正常返回的任何數據可用,直到請求的數量,而比等待收到所要求的全部金額。

返回值(當> 0時)將是接收到的字節數,因此如果您想確保接收所有內容,則可以在循環中調用它。

或者,您可以通過MSG_WAITALL標誌:

此標誌請求的操作塊,直到完全滿足請求。但是,如果捕獲到信號,發生錯誤或斷開連接,或者接收到的下一個數據的類型與返回的數據類型不同,那麼調用返回的數據的數據量可能會比請求數少。

你的情況

所以,你可以這樣做:

ssize_t bytes = recv(f_sockd, &fsize, sizeof(fsize), MSG_WAITALL); 

if(bytes == sizeof(fsize)) 
{ 
    /* received everything */ 
} 
else 
{ 
    /* something went wrong */ 
} 
+0

服務器發送20個字節,客戶端收到1801745249 O.o爲什麼? :( – polslinux