2017-12-10 11 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%のファイルを受信します。

使用してテストファイルImはJPEGであり、それは残りの242 * 32 1024 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のmanページに次のような内容が含まれています。 "ストリームソケットピアが正常にシャットダウンした場合、戻り値は0(従来の"ファイルの終わり "の戻り値)になります。 ...したがって、クライアントコードでは、ソケットの読み取り値を "ファイルの終わり"として処理する必要があります。 – TonyB

答えて

0
  • recvBuff == 0真なることはありません。
  • recvBuff == 0の代わりにテストする必要がありますbytesReceived == 0をテストしていません。

したがって、クライアントのコピー終了ループは終了しないため、出力ファイルを決して閉じることはありません。

その他の問題:

  • は、APIがあまりにも問題があるfread()fopen()などを使用しないでください。 open(),read(),write(),close()を使用してください。
  • ファイルの最後に0バイトを送信することは無意味です。
+0

私はあなたが示唆した変更を実装しましたが、EoSを受け取ったことのないような理由で依然として固執しているようです。 – Alphala7

+0

したがって、あなたはまだ 'if(bytesReceived == 0){break; } 'クライアントの読み取りループで正しく、またはサーバーがソケットを閉じていません。 – EJP

関連する問題