2017-12-10 19 views
1

저는 C를 처음 사용하고 있으며, 저의 삶을 위해 디버깅 할 수 없다는 문제가 있습니다. 나는 서버에서 클라이언트로 파일을 보내는 매우 간단한 작업을 시도하고있다.서버에서 클라이언트로 파일을 복사 할 때 문제가 발생했습니다.

서버 코드 :

void send_file(int socket, char *filename[100]) 
{ 

char fname[100] = "./upload/"; 

strcat(fname,filename); 

printf("%s%", fname); 

FILE *fp = fopen(fname,"rb"); 

    if(fp==NULL) 
    { 
     printf("File open error"); 
    } 

    while(1) 
    { 
     unsigned char buff[1024]={0}; 
     int nread = fread(buff,1,1024,fp); //read 256 byte chunk of file 
     printf("Bytes read %d \n", nread);   

     // If read was success, send data. 
     if(nread > 0) 
     { 
      write(socket, buff, nread); 
     } 
     if (nread == 0) 
     { 
    write(socket, buff, nread); 

      if (feof(fp)) 
    { 
     printf("Transfer Complete, ID: %d\n",socket); 
     break; 
    } 
      if (ferror(fp)) 

       printf("Read Error\n"); 

      break; 
     } 

    } 
fclose(fp); 

}

그래서이 코드, 나는 파일 이름을 256 개 바이트 청크에서 파일을 읽은 다음 클라이언트가 다음 읽는을 작성합니다.

클라이언트 코드 :

void get_file(int socket, char *fname[100]) { 

int bytesReceived = 0; 
char recvBuff[1024]; 
memset(recvBuff, '0', sizeof(recvBuff)); 

FILE *fp; 

fp = fopen(fname, "w+"); 

if(NULL == fp) 
{ 
    printf("Error opening file"); 

} 

//Receive data in chunks of 256 bytes 

fseek(fp, 0, SEEK_SET);//point to start of file 

while(1) 
{ 

bytesReceived = read(socket, recvBuff, 1024); 

if (bytesReceived > 0) 
{ 
    fwrite(recvBuff, 1,bytesReceived,fp); 
} 

if (recvBuff == 0) {  
    break; 
} 
} 

if(bytesReceived < 0) 
{ 
    printf("\n Read Error \n"); 
} 

printf("\nFile OK....Completed\n"); 
fclose(fp); 

은}

이 문제는 그것을 잘 그것을 읽고 있지만 전송하지 않는 것, 양쪽 내가 서버 측에서 파일을 읽을 때 작동하는 것입니다 그것의 모든. 클라이언트는 매회 약 99 %의 파일을받습니다.

그것은 클라이언트 측 루프는 전체 파일을 기록하지 않습니다 때문에 완료 결코 것, 임 사용하여 테스트 파일은 JPEG이며 1024 * 32 나머지 242 33010.

에서 32768를 수신 바이트가 쓰여지지 않고 루프가 중단되는 빈 쓰기를 서버가 보냈음에도 루프가 종료되지 않는 것 같습니다.

SIGINT를 서버에 보내는 것은 클라이언트 루프를 끝내지 만 나머지 파일도 보냅니다.

내가 잘못하고있는 것에 대한 통찰력은 정말 좋을 것입니다. 감사합니다!

편집 :

AS는 기능을 수행하는 코드를 요청 하였다.

void *client_handler(void *socket_desc){ 

int connfd = *(int *) socket_desc; 
char recv_option[128]; 
char filename[100]; 
size_t n; 
size_t k; 

while (1) { 

char recv_option[128] = ""; 

readn(connfd, (unsigned char *) &n, sizeof(size_t)); 
readn(connfd, (unsigned char *) recv_option, n); 

printf("Recieved: %c\n", recv_option[0]); 

if (recv_option[0] == 'a') { 
    send_servertime(connfd); 
    } 

if (recv_option[0] == 'b') { 
    send_uname(connfd); 
} 

if (recv_option[0] == 'c') { 
    send_filenames(connfd); 
} 

if (recv_option[0] == 'd') { 

    readn(connfd, (unsigned char *) &k, sizeof(size_t)); 
    readn(connfd, (unsigned char *) filename, k); 

    send_file(connfd, &filename); 

    } 
}//whileloop 

shutdown(connfd, SHUT_RDWR); 
close(connfd); 

printf("Thread %lu exiting\n", (unsigned long) pthread_self()); 

shutdown(connfd, SHUT_RDWR); 
close(connfd); 

return 0; 
} // end client_handler() 
+0

'recvBuff == 0'은 항상 false입니다. – Mat

+0

내가 recvBuff으로 해결할 것이라고 내가 0으로 쓰기를 보낼 생각? – Alphala7

+0

FYI : 소켓의 "read()"는 플래그가 설정되지 않은 "recv()"처럼 동작합니다. "recv()"에는 Ubuntu Linux 맨 페이지에 다음 내용이 포함되어 있습니다. "스트림 소켓 피어가 정상 종료를 수행하면 반환 값은 0 (기존"파일 끝 "반환)입니다." ...따라서 클라이언트 코드는 "파일 끝"으로 소켓에서 0을 읽어야합니다 ... – TonyB

답변

0
  • recvBuff == 0 사실 일 수 없다.
  • recvBuff == 0 대신 테스트해야하는 것은 bytesReceived == 0입니다.

따라서 클라이언트에서 스트림의 끝을 무시하므로 클라이언트 복사본 루프가 종료되지 않으므로 출력 파일을 닫지 않습니다.

다른 문제 :

  • fread(), fopen()는 등 API는 너무 문제가 사용하지 마십시오. open(), read(), write(), close()을 사용하십시오.
  • 파일 끝에 0 바이트를 보내는 것은 의미가 없습니다.
+0

내가 제안한 변경 사항을 구현했지만 여전히 EoS를받지 못하는 것처럼 어떤 이유로 든 해결해야 할 것 같습니다. – Alphala7

+0

그래서 당신은 아직'if (bytesReceived == 0) {break; }'클라이언트 읽기 루프에서 올바로 수행했거나 서버가 소켓을 닫지 않았습니다. – EJP