2012-04-22 6 views
1

클라이언트에서 서버로 파일을 보내기위한 간단한 클라이언트 - 서버 응용 프로그램이 있습니다. 클라이언트는 미리 정의 된 크기 (예 : 512)의 청크로 파일을 보냅니다. 서버는 파일을 동일한 크기의 청크로 수신합니다. 클라이언트 측 소켓은 서버가 전체 파일을받은 후 ack를 보낼 때까지 닫히지 않습니다.두 번째 호출에서 recv() 블록

은 무엇 발생하는 것입니다 :

  1. 클라이언트가 (() 호출을 보낼 수) 전체 파일을 보내 관리, 모든 덩어리를 의미한다.
  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

+0

네트워크가 다른 것을 필터링하는 경우 첫 번째 청크도 필터링해야합니다. 버그는 항상 가능성이지만 어떤 종류입니까? 루프에 수신 된 모든 청크에 대해 동일한 코드입니다. –

+0

C 코드에는 가능한 한 많은 버그가 소스 파일에 있습니다 (그 이상의 경우도 있음). 코드의 관련 부분을 보지 않아도 누구도 도움을 줄 수 없습니다. – Mat

답변

0

귀하의 전송 코드가 잘못,이 둘 이상의 덩어리를 전송하지 않습니다 정상적인 상황 (즉, 쓰기는 한 번에 전체 덩어리를 씁니다).
내부 루프 이후에 bytesSent을 재설정하지 않았기 때문입니다. 처음에는 sendBuf 이후에 == FILE_READ_CHUNK_SIZE이 될 가능성이 있으며, while 조건은 항상 false가됩니다.

그래서 하나의 버퍼 만 보내고 있습니다.

는 (아마 당신의 코드에서 몇 가지 이상의 오류가 있습니다. 짧은 쓰기가 발생하는 경우 당신은 예를 들어 (당신이 당신의 버퍼의 머리를 다시 보낼 것이다) 버퍼의 잘못된 부분을 보낼 수 있습니다.)

+0

감사합니다. 당신은 내 버그를 발견 :) –

관련 문제