2012-04-22 8 views
1

私はクライアントからサーバーへファイルを送信するためのシンプルなクライアントサーバーアプリケーションを持っています。 クライアントは、ファイルをあらかじめ定義されたサイズのチャンク(512など)で送信します。 サーバは同じサイズのチャンクでもファイルを受信します。 ファイル全体を受信した後にサーバーがackを送信するまで、クライアント側のソケットは閉じられません。2番目の呼び出しからのrecv()ブロック

何が起こるかということです:クライアントは、すべてのチャンクを意味し、(()の呼び出しを送信する)ファイル全体を送信するために管理し

  1. サーバは最初のチャンクのみを取得(recv()コール)するため、recv()コールは最初のコールで512を返し、2番目のコールでブロックします。

このような現象は、どのような原因が考えられますか?

ここに関連する部分があります。

送信\は機能を受信:

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

+0

ネットワークが何かをフィルタリングしていたら、最初のチャンクもフィルタリングしていたはずです。バグは常に可能性ですが、どんな種類ですか?これは、すべてのチャンクに対して、ループ内で\送信されたものと同じコードです。 –

+0

Cコードには、ソースファイルに文字が存在する可能性があります。コードの関連部分を見ることなく、誰もあなたを助けることはできません。 – Mat

答えて

0

あなたの送信コードが間違っている、それがもとで複数のチャンクを送信しません通常の状況です(つまり、書き込みは一度に完全なチャンクを書き込みます)。
内部ループの後にbytesSentをリセットしないためです。最初のsendBufの後には== FILE_READ_CHUNK_SIZEになる可能性があります。その後、whileの条件は常にfalseになります。

したがって、バッファを1つだけ送信しています。

は(おそらくあなたのコード内のいくつかのより多くのエラーがあります。短い書き込みが発生した場合には、例えば(あなたがバッファの先頭を再送信します)バッファの間違った部分を送信することがあります。)

+0

ありがとう!あなたは私のバグを発見:) –