[英]Send a File with socket in C for 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是一個愚蠢的想法嗎?
假設file_size
是您要發送的總字節數,那么for
循環將只發送file_size - 1
個字節。 換句話說,你是一個人。 從0
開始而不是修復此問題:
for (n=0; n<file_size; n++)
{ //..
您捕獲send()
的返回值,但不檢查它是否成功。
您正在從recv()
處理0
返回值與錯誤相同。 由於您在從函數返回-1
后沒有顯示您所執行的操作,因此我不知道這是否會導致您的問題。
send()
和recv()
上的某些錯誤是“軟”的,因為您可以重試這些特定錯誤的操作。 一個這樣的錯誤是EINTR
,但檢查系統上的文檔以查看是否還有其他文件。
為了優化性能並簡化代碼,您可以使用splice()+管道。 Sendfile使您可以在文件描述符之間“轉發”數據,而無需將副本復制到用戶空間。
您確定已復制了正確的代碼嗎? 因為它不會編譯,所以在最后一個中有一個}與相應的{不匹配}。
另外,您如何知道文件大小? 如果它通過套接字作為整數發送,請記住源和目標機器的可能字節順序。
無論如何,你一次只讀一個字節,你應該這樣改進:
編輯:使用緩沖區而不是額外的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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.