2013-06-25 52 views
1

我正在寫一個小而簡單的服務器(在C語言的Linux站)。發送一個文件在Linux中的C使用套接字

一個客戶端向我的服務器請求一個文件,我的服務器向另一個服務器請求這個文件,將它發送到我的服務器。

我的服務器在發送給客戶端之前不應該接收所有的文件,但必須發送文件的字節,以便他們到達。

這是在學校的練習,所以我不能將自己從這個要求中分離出來。

我已經實現了下面解釋的功能。問題是客戶端收到了不確定的字節數,並且從來沒有收到整個文件。

int Recv_and_send_file (int socketa, int socketb, char *buffer, size_t file_size){ 

    size_t n; 

    ssize_t nread; 

    ssize_t nwritten; 

    char c; 

    for (n=1; n<file_size; n++) 
    {   
      nread=recv(socketa, &c, 1, 0); 

      if (nread == 1) 
      { 
       nwritten = send(socketb,&c,1,0); 
      } 
      else if (nread == 0) 
      { 
       *buffer = 0; 
       return (-1); /* Errore */ 
      } 
      else 
       return (-1); /* Errore */ 
      } 
    } 
    *buffer = 0; 
    return (n); 
} 

有人可以告訴我我在哪裏錯了嗎?

更改服務器和客戶端上的值SO_SNDBUF和SO_RCVBUF是否是一個愚蠢的想法?

回答

1

假設file_size是您想要發送的字節總數,那麼您的for循環將只發送file_size - 1字節。換句話說,你是一個人。從0開始,而不是解決這個問題:

for (n=0; n<file_size; n++) 
    { //.. 

您捕捉send()的返回值,但你不檢查,看它是否是成功還是失敗。

您正在處理從recv()返回的0返回值與錯誤相同。既然你沒有顯示你的函數返回-1後你做了什麼,我不知道這是否可能導致你的問題。

send()recv()上的某些錯誤是「軟」的,因爲您可以重試這些特定錯誤的操作。其中一個錯誤是EINTR,但請檢查系統上的文檔以查看是否有其他文檔。

1

爲了優化性能並簡化代碼,可以使用splice()+管道。 Sendfile使您能夠在文件描述符之間「轉發」數據,而不需要複製到用戶空間。

+0

謝謝您的回答,但它要求我有明確的方式來發送字節每字節 – user2510406

1

你確定你已經複製了正確的代碼嗎?該部分原本不會編譯,最後一個部分有一個與相應的{}不匹配的部分。

另外,您如何瞭解文件大小?如果它是以整數形式通過套接字發送的,請記住源機器和目標機器的可能字節順序。

反正你每次讀一個字節,你應該提高這樣說:

編輯:使用緩衝區,而不是額外的buff [2048];

int Recv_and_send_file (int socketa, int socketb, char *buffer, size_t file_size){ 

    ssize_t nread; 
    ssize_t nwritten; 
    ssize_t bLeft=file_size; 

    while (bLeft > 0) 
    { 
     nread=recv(socketa, buffer, bleft, 0); 
     if (nread > 0) 
     { 
      nwritten = send(socketb, buffer, nread, 0); 
      bLeft -= nread; 
      buffer+=nread; 
     } 
     else if (nread == 0) 
     { 
      // I think this could raise a memory exception, read below 
      *buffer = 0; 
      return (-1); /* Errore */ 
     } 
     else 
     { 
      return (-1); /* Errore */ 
     } 
    } 
    // If buffer is allocated with file_size bytes this one will raise a memory exception 
    // *buffer = 0; 
    return (file_size-bLeft); 
} 
+0

第二個服務器,發送文件之前,發送到我的服務器上的文件的大小,以使我的服務器上做一個malloc和創建緩衝區,在函數中顯示爲輸入。感謝您的回答,我儘快嘗試此代碼! – user2510406

+0

我不知道,緩衝區已經分配了足夠的空間,所以代碼將不同,不需要額外的buff [2048]。 我將編輯響應以使其更好,並在緩衝區中存儲文件的內容。 –

相關問題