소켓을 통한 파일 전송, 바이트가 적은 최종 크기
-
22-08-2019 - |
문제
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 );
}