2012-04-22 115 views
1

我有一個簡單的客戶端服務器應用程序用於將文件從客戶端發送到服務器。 客戶端以預定義大小的塊(比如512)發送文件。 服務器也以大小相同的塊接收文件。 直到服務器在收到整個文件後發送一個確認後,客戶端的套接字才關閉。第二次調用recv()塊

發生什麼事是:

  1. 客戶端管理髮送(send()方法調用)整個文件,意味着它的所有數據塊。
  2. 服務器只管理第一個塊的recv()調用,意味着recv()調用在第一次調用時返回512,在第二次調用時調用它的塊。

這種行爲的原因是什麼?

以下是相關部分。

發送\接收功能:

int sendBuf(int sockFd, char* buf, int size){ 
    int bytesSent = 0; 
    while (bytesSent < size){ 
     bytesSent += send(sockFd, buf, size, 0); 
    } 
    return bytesSent; 
} 


int sendInt(int sockFd, int num){ 
    uint32_t nbo_num = htonl(num); 
    return sendBuf(sockFd, (char*)&nbo_num, sizeof(nbo_num)); 
} 


int getBuf(int sockFd, char* buf, int size){ 
    int bytesRecv = 0; 
    while (bytesRecv < size){ 
     bytesRecv += recv(sockFd, buf, size, 0); 
    } 
    return bytesRecv; 
} 


int getInt(int sockFd, int *num){ 
    int temp, bytesRecv; 
    bytesRecv = getBuf(sockFd, (char*)&temp, sizeof(int)); 
    *num = ntohl(temp); 
    return bytesRecv; 
} 

服務器:

printf("%s  New file was created.\n",tStr); 

/* get file data */ 
char buf[FILE_READ_CHUNK_SIZE] = {0}; // FILE_READ_CHUNK_SIZE is the maximal read amount 
int bytesWritten = 0, bytesLeft = fileSize, _size=0, chunkNo=0; 
bytesRecv = 0; 

while (bytesLeft > 0){ 
    _size = (bytesLeft > FILE_READ_CHUNK_SIZE) ? FILE_READ_CHUNK_SIZE : bytesLeft; 
    bytesRecv = getBuf(newsockfd, buf, _size); 
    int _bytesLeft = bytesRecv; 
    bytesWritten = 0; 
    while (_bytesLeft > 0){ 
     bytesWritten = fileInfoWrite(fileInfo, buf, _bytesLeft); 
     _bytesLeft -= bytesWritten; 
    } 
    chunkNo++; 
    printf("%s  chunk #%d: received %d bytes\n",tStr , chunkNo, bytesRecv); 
    bytesLeft -= bytesRecv; 
} 
printf("%s Finished getting file #%d.\n",tStr ,i+1); 

/* send ack to the client */ 
bytesSent = sendInt(newsockfd, 1); 
printf("%s Sent the client an ack for file #%d.\n",tStr ,i+1); 

客戶:

/* send the entire data of the file */ 
printf(" Sending file data\t\t... "); 
char buf[FILE_READ_CHUNK_SIZE] = {0}; // FILE_READ_CHUNK_SIZE is the maximal read amount 
int numOfChunks=0, bytesRead = 0, bytesLeft = filesArr[i]->fileSize ; 
bool eof = false; 
bytesSent = 1; 

while (bytesLeft > 0){ 
    bytesRead = fileInfoRead(filesArr[i], buf, &eof); 
    int _bytesLeft = bytesRead; 
    while (bytesSent < _bytesLeft){ 
     bytesSent = sendBuf(sockFd, buf, _bytesLeft); 
     _bytesLeft -= bytesSent; 
    } 
    //printf(" chunk #%d: sent %d bytes\n", numOfChunks+1, bytesRead); 
    bytesLeft -= bytesRead; 
    numOfChunks++; 
} 
printf("Success.\n"); 

/* get ack from server */ 
int ack=0; 
bytesRecv = getInt(sockFd, &ack); 
if (bytesRecv!=4 || ack!=1){ 
    printf("Server ack is invalid.\n"); 
} 
printf("Finished sending file #%d.\n",i+1); 
+0

這裏最可能的問題是網絡丟棄/過濾的東西,或者是你的代碼在某處的錯誤。 – Mat 2012-04-22 09:30:30

+0

如果網絡沒有任何東西,那麼它也應該過濾第一個塊。一個bug總是一種可能性,但是是一種什麼樣的?這是所有塊的代碼,因爲它們是在一個循環中發送和接收的... – 2012-04-22 09:45:51

+0

C代碼中存在儘可能多的錯誤,因爲它的源文件中有字符(可能甚至超過這些)。沒有看到你的代碼的相關部分,沒有人可以幫助你。 – Mat 2012-04-22 09:47:24

回答

0

您發送代碼是錯誤的,它不會發送多塊下正常情況下(即寫入一次寫入完整的塊)。
這是因爲在內循環之後,您不會重置bytesSent。在第一個sendBuf之後,機會將會是== FILE_READ_CHUNK_SIZE,並且在此之後,條件永遠是錯誤的。

所以你只發送一個緩衝區。

(有可能是你的代碼的一些更多的錯誤。如果很短的寫操作發生您要發送緩衝區的錯件(你會重新發送緩衝區的頭)的實例。)

+0

感謝分配墊!你發現我的錯誤:) – 2012-04-22 12:23:32