2009-03-26 2 views
6

C에서 소켓을 통해 파일을 보내려고합니다. 그러나 서버에서 1000000 바이트 파일에 대해 64 바이트 패킷을 보내고 약 999902 바이트를 대상 파일.소켓을 통한 파일 전송, 바이트 수가 적은 최종 크기

while ((n = read(sd, buffer_in, BUFSIZE))) // BUFSIZE = 64 
{ 
    if(n<0) 
    { 
     printf("Fail.\n"); 
     fclose(archivo); 
     return -1; 
    } 

    if(fwrite(buffer_in, n, 1, f) !=1) 
    { 
     printf("fwrite error.\n"); 
     fclose(archivo); 
     return -1; 
    } 

    bytes+=n; 
} 

printf("We received %d bytes", bytes); 

로컬 TCP/IP 소켓을 통해 사용하는 경우에는 작동하지만 저속 연결에서는 작동하지 않습니다. 디버깅을 통해 EOF 근처에 많은 64 바이트 청크와 30 바이트 청크가 있음을 알 수 있습니다. 모든 데이터 (> 1 바이트)를 사용할 수있을 때 호출이 반환되기 때문에 read()에서 더 적은 바이트를 얻을 수 있다는 것을 알고 있습니다. 그러나이 조건은 잠시 멈추지 말아야합니까? n == 0 일 때 반환해야합니다. 더 이상 데이터 (EOF)가 아닙니다.

당신의 도움을 위해 Thx.

(EDIT)는 다음과 같이 코드를 보내기

:

while (n=read(file_fd, buffer, BUFSIZE)) 
{ 
    write (sdaccept, buffer, n) 
} 

나는 읽기()와() 쓰기 모두 N < BUFSIZE를 반환 할 수 있다는 것을 알고 있지만,해야하지 그 밖에이 루프 작업을 따라 ? 나는 n을 더하고 정확한 크기 인 1000000을 반환합니다.

(EDIT II) 10,673 바이트와 C 소스와 테스트

는 대상 파일의 처음 98 바이트를 결여 제외 손상없이 10,575 수신 !!!

+0

약 999,902를? 아니면 정확히? – paxdiablo

+0

이 코드에는 명백한 결함이 없습니다. 전송 코드도 함께 표시하십시오. – Alnitak

+0

특히 이상한데, 64가 1000000으로 정확히 나뉘어 졌으므로 정확히 –

답변

11

제공된 송신 코드는 소켓의 write() (또는 send())가 전체 버퍼를 쓰지 않아도된다는 사실을 무시합니다.

write()/send()는 하위 시스템이 더 많은 데이터 수신을 거부하면 부분적으로 쓰거나 쓰지 않기로 결정할 수 있습니다. 예를 들어 네트워크 하위 시스템에 보낼 데이터의 대기열이있을 수 있으며이 대기열은 이미 가득 찼음). 연결 속도가 느릴 확률이 높습니다.

송신 측은 write()의 리턴 값을 검사하여 실제로 얼마나 많은 데이터가 기록되었는지 감지하고 그에 따라 조정해야합니다.

쓰기는 다음과 같이 어떻게 든 수행해야합니다 :

int readAmount; 
while(readAmount = read(file_fd, buffer, BUFSIZE) > 0) 
{ 
    int totalWritten = 0; 
    do { 
     int actualWritten; 
     actualWritten = write (sdaccept, buffer + totalWritten, readAmount - totalWritten); 
     if(actualWritten == - 1) { 
      //some error occured - quit; 
     } 
     totalWritten += actualWritten; 
    } while(totalWritten < readAmount); 
} 
+0

보내는 쪽 코드가 추가되었습니다. –

+0

코드를 보내면 내가 설명한 문제가 발생하기 쉽습니다. 제안 된 수정 사항이 추가되었습니다. – sharptooth

+0

아직 999902 바이트를 전송합니다 !!!! :(:( –