2011-02-12 13 views
1

ファイルポインタを使ってファイルを読み書きすると、約8.6MBのデータを送信し、さらに8.6MBを受信すると、8.3MBのファイルをTCP経由で転送する必要があります。ファイルのサイズは8.3 MBですが、sendとrecvの呼び出しの出力を計算することでデータのサイズを調べます。さらに、そのプロパティを見てファイルのサイズを別々に確認すると、転送は3〜5 MB(毎回変わります)ですが、ファイルポインタの代わりにファイルディスクリプタを使用し、正確に8.3 MBのデータとファイルのプロパティサイズを送信し、recvすると、8.3 MBが表示されます。だから、ファイルポインタを使用する際の問題は何ですか?なぜファイル記述子の場合には削除されますか?しかし、ファイル記述子を使用すると、送信したテキストファイルを読み取ることができません。テキストエディタはファイルにバイナリデータを表示します。私は、ファイルの使用を交換するだけであれば何が起こっているかのビットを取得...事前に助けと感謝してくださいファイルポインターを使用してTCP経由でファイルを転送する際の問題

server.cpp

#include "server.h" 
void server() 
{ 
    int fd = open("out.txt",O_WRONLY); 
    struct sockaddr_in sin; 
    socklen_t addr_size; 
    char buf[MAX_LINE]; 
    int len; 
    int s, new_s; 
    /* build address data structure */ 
    bzero((char *) & sin, sizeof (sin)); 
    sin.sin_family = AF_INET; 
    sin.sin_addr.s_addr = INADDR_ANY; 
    sin.sin_port = htons(SERVER_PORT); 
    printf("File Descriptor : %d", fd); 
    /* setup passive open */ 
    if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) 
    { 
     perror("simplex-talk: socket"); 
     exit(1); 
    } 
    if ((bind(s, (struct sockaddr *) & sin, sizeof (sin))) < 0) 
    { 
     perror("simplex-talk: bind"); 
     exit(1); 
    } 
    listen(s, MAX_PENDING); 
    // wait for connection, then receive and print text */ 
    while (1) 
    { 
     if ((new_s = accept(s, (struct sockaddr *) & sin, &addr_size)) < 0) 
     { 
      perror("simplex-talk: accept"); 
      exit(1); 
     } 
     float total = 0; 
     printf("File Descriptor : %d", fd); 
     while (len = recv(new_s, buf, MAX_LINE, 0) && strcmp(buf,"close")) 
     { 
      buf[len] = 0; 
      total = total+len; 
      //write(stdout, buf, len); 
      write(fd, buf, len); 
      //printf("%fKB and %fMB\n",total/1024, total/(1024*1024)); 
     } 
     printf("File Descriptor : %d", fd); 
     close(new_s); 
    } 
} 

client.cpp

#include "client.h" 
void client(int argc, char** argv) 
{ 
    int fd = open("/home/nikku/Desktop/data.txt",O_RDONLY); 
    if (fd < 0) perror("File not opened\n"); 
    struct hostent *hp; 
    struct sockaddr_in sin; 
    char *host; 
    char buf[MAX_LINE]; 
    int s; 
    int len; 
    host = argv[1]; 
    if (argc == 2) 
    { 
     host = argv[1]; 
    } 
    else 
    { 
     fprintf(stderr, "usage: simplex-talk host\n"); 
     exit(1); 
    } 
    /* translate host name into peer’s IP address */ 
    gethostname(host,20); 
    printf("%s\n",host); 
    hp = gethostbyname(host); 
    if (!hp) 
    { 
     fprintf(stderr, "simplex-talk: unknown host: %s\n", host); 
     exit(1); 
    } 
    /* build address data structure */ 
    bzero((char *) & sin, sizeof (sin)); 
    sin.sin_family = AF_INET; 
    bcopy(hp->h_addr, (char *) & sin.sin_addr, hp->h_length); 
    sin.sin_port = htons(SERVER_PORT); 
    /* active open */ 
    if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) 
    { 
     perror("simplex-talk: socket"); 
     exit(1); 
    } 
    if (connect(s, (struct sockaddr *) & sin, sizeof (sin)) < 0) 
    { 
     perror("simplex-talk: connect"); 
     close(s); 
     exit(1); 
    } 
    printf("Connection Succeeded\n"); 
    /* main loop: get and send lines of text */ 
    float total = 0; 
    while (read(fd, buf, MAX_LINE)) 
    { 
     //usleep(1000);; 
     len = strlen(buf) + 1; 
     total += send(s, buf, len, 0); 
     //printf("%fKB and %fMB\n",total/1024, total/(1024*1024)); 
    } 
    send(s, "close", 6, 0); 
    close(fd); 
} 

ておりませんポインタを持つ記述子を使用し、読み書きにfgetsとfputsを使用すると、ファイル転送が正しく行われません。しかし、私がファイル記述子を使用する場合、私は送信したテキストファイルを読むことができません。テキストエディタはファイルにバイナリデータを表示します。

+2

あなたのコードに問題がある場合、あなたのコードを見ることができない限り誰もあなたを助けることができません。あなたのコードを投稿してください。 –

答えて

1
while (read(fd, buf, MAX_LINE)) 
{ 
    //usleep(1000);; 
    len = strlen(buf) + 1; 
    total += send(s, buf, len, 0); 
    //printf("%fKB and %fMB\n",total/1024, total/(1024*1024)); 
} 

問題は、readがそうstrlen(buf)が潜在的に危険であるゼロバイトを読み取ることを保証はありません、ここにあります。 lenstrlen(buf) + 1に設定すると、0バイトをエンコードするとソケット全体に送信されますが、0バイトを読み取らない場合はstrlenが配列の最後を超えて読み込まれ、 'junk'ソケットを横切って。

fdから実際に読み取られたバイト数を知るために、戻り値をreadとして保存することは賢明でしょう。

while (len = recv(new_s, buf, MAX_LINE, 0) && strcmp(buf,"close")) 
{ 
    buf[len] = 0; 
    total = total+len; 
    //write(stdout, buf, len); 
    write(fd, buf, len); 
    //printf("%fKB and %fMB\n",total/1024, total/(1024*1024)); 
} 

あなたの受信側は、あなたが手動であなたが実際に実際にrecv場合はこれを行うための部屋を持っていません0注意してバッファを終了するようにrecvへの各呼び出しはゼロバイトが含まれないことを前提としているようですbufMAX_LINE要素のみで構成されているため、MAX_LINEバイトを受け取ります。あなたの書き込みはどんな場合でも長さによって制限されるので、buf[len] = 0;をする必要はありません。

+0

ありがとうございます!問題がある – chinmayaposwalia

関連する問題