문제

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 소켓을 통해 사용하면 작동하지만 느리게 연결되지는 않습니다. 디버깅을 통해 64 바이트 덩어리와 EOF 근처에 30 바이트 덩어리가 많이 나타납니다. 데이터 (> 1 바이트)를 사용할 수있을 때 통화가 반환되므로 read ()에서 바이트를 적게 얻을 수 있다는 것을 알고 있습니다. 그러나이 상태는 한동안 잡히지 않아야합니까? n == 0이면 더 이상 데이터가 아닙니다 (EOF).

당신의 도움에 대한 thx.

(편집하다)

다음과 같이 코드 보내기 :

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

read ()와 write ()가 모두 n <bufsize를 반환 할 수 있다는 것을 알고 있지만이 루프는 그에 따라 작동하지 않아야합니까? N을 추가하고 정확한 크기 인 1000000을 반환합니다.

(편집 II)

10673 바이트가있는 C 소스로 테스트 된 대상 파일에 처음 98 바이트가 없다는 점을 제외하고는 손상없이 10575를 수신합니다 !!!

도움이 되었습니까?

해결책

제공된 전송 코드는 소켓의 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 );
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top