2016-10-22 3 views
0

다음 코드는 실제 파일이 별도의 파일로 수신되는 경우 동일한 파일 ("/ tmp/frame"), 에 데이터를 계속 수신합니다. 서버가 파일 받기를 시작한 후 닫히지 않아 동일한 파일에서 다음 파일의 데이터를 계속 수신하는 것으로 보입니다.소켓 전송시 파일이 계속 무한 데이터를 수신합니다.

(코드의 주석이 문제를 해결하지만, 파일의 전송을 지연)

가 보낸 사람 :

screenshot ptr_screen; 
CHAR Block[4096], buffer[512]; 
int BytesRead, iResult; 
for (;;) { 
    memset(Block, 0, sizeof(Block)); 
    memset(buffer, 0, sizeof(buffer)); 

    ptr_screen.Start(); 

    FILE *fp = fopen("screen.jpg", "rb"); 
    if (!fp) { break; } 

    fseek(fp, 0, SEEK_END); 
    int32_t file_size = ftell(fp); 
    fseek(fp, 0, SEEK_SET); 

    iResult = send(socket_, (char*)&file_size, sizeof(file_size), 0); 
    if (iResult == SOCKET_ERROR) { fclose(fp); break; } 

    while (file_size > 0) { 
     BytesRead = fread(Block, 1, sizeof(Block), fp); 
     if (BytesRead <= 0) { break; } 

     iResult = send(socket_, Block, BytesRead, 0); 
     if (iResult != BytesRead) { break; } 

     file_size -= BytesRead; 
    } 
    fflush(fp); 
    fclose(fp); 
    //if (recv_to(socket_, buffer, sizeof(buffer), 0, 5000) <= 0) 
     //break; 
} 

수신기 :

int iResult; 
char Block[512]; 
int32_t file_size; 
for(;;) { 
    FILE* fp = fopen("/tmp/frame", "wb"); 
    if(!fp) { break; } 

    memset(Block, 0, sizeof(Block)); 
    iResult = recv_to((char*)&file_size, sizeof(file_size), 10); 
    if(iResult <= 0) { break; } 

    while(file_size > 0) { 
     iResult = recv_to(Block, sizeof(Block), 10); 
     if(iResult <= 0) { break; } 

     if(fwrite(Block, 1, iResult, fp) != (unsigned)iResult) { return; } 
     file_size -= iResult; 
    } 
    fclose(fp); 
    system("mv /tmp/frame /tmp/stream.jpg"); 
    //send(socket_, "OK", strlen("OK"), 0); // response 
} 

답변

2

TCP가있다 스트림 프로토콜. 수신자는 일반적으로 발신자가 전송 한 데이터와 동일한 청크로 분류 된 데이터를 수신하지 않습니다. 청크는 본질적으로 임의로 분류됩니다.

특히, 보낸 사람이 파일의 마지막 부분을 보낸 다음 즉시 크기와 첫 번째 청크를 새 파일에서 보내면 수신자가 마지막 청크, 크기 및 부분을 수신 할 가능성이 완전히 있습니다 다음 파일의 첫 번째 청크의 모든 블록을 한 블록에 함께 표시합니다. file_size은 네거티브로 바뀌며, 이것은 당신을 한 번에 안쪽 루프에서 꺼낼 것입니다. 그러나 다음 파일의 중간에서 임의의 데이터를 file_size으로 읽으려고합니다. 아마도 매우 큰 정수를 형성 할 것입니다. 그래서 내부 루프가 더 이상 종료되지 않는 것입니다.

내부 루프에서 max(sizeof(Block), file_size) 바이트를 읽으므로 파일 경계를 넘지 않습니다.

+0

내 Linux 서버에 대한 예를 들어 줄 수 있습니까? –

+0

예를 들면? –

+0

어떻게이 코드 조각을 recv_to (block, sizeof (Block), 10) 변경할 수 있습니까? 그래서이 문제가 계속 발생하지 않습니까? –

관련 문제