• ベストアンサー

ファイルの受信

c言語で、クライアント側のファイルを開き、内容をそのまま送信しているはずなのですが上手くいきません。 テキストファイルは正しく送れるようですが、他の実行ファイルなどはダメみたいです。 送信側は、"rb"でオープンし,whileで fread(send_buf,1024,1,fp); send(soc,send_buf,strlen(send_buf),0); を繰り返しています。send_buf[1025]です。 送信側は Recv_buf[1025];で size = recv(soc,Recv_buf,1024,0); fwrite(Recv_buf,size,1,fp); whileで繰り返し受信がなくなったらselectでタイムアウトしています。 いろいろ調べたのですがSleepが必要らしいそうですが・・・どうなんでしょう?

  • earth
  • お礼率5% (17/300)

質問者が選んだベストアンサー

  • ベストアンサー
  • mi-si
  • ベストアンサー率35% (200/567)
回答No.2

strlenでは、文字列の文字数しかチェック出来ませんので、バイナリを送信すると動作が予期出来なくなります。\0が出てくる迄の文字数を数えているだけなので、実際に読み込んだバイナリの途中で\0が出てくると、それ以降のデータが切られて送信されるため、ファイルが壊れます。 freadで読み込んだbyte数を知る事が出来るので、 #1さんのやり方を試してみるのが良いかと思います。

その他の回答 (1)

  • notnot
  • ベストアンサー率47% (4847/10260)
回答No.1

>fread(send_buf,1024,1,fp); >send(soc,send_buf,strlen(send_buf),0); ファイルから(最大)1024バイト読み込んで、その先頭から 0 が現れるまでを送信しているので駄目でしょう。 わからなければstrlenの仕様を調べてください。 未テストですが、 n=fread(send_buf,1,1024,fp); send(soc,send_buf,n,0); でどうでしょう?

関連するQ&A

  • Winsockを利用した単純なファイル送信プログラムについて

    こんばんは。 何度もこの掲示板を利用させていただいている者です。 WinsockのUDPを用いて簡単なファイル送信プログラムを作っています。UDPを使わずに、TCPを使用したほうが良いのでは?とのご指摘をいただきましたが、まずは、UDPを利用した単純なファイル送信プログラムを作ってみたいと思っています。 しかし、送信側から受信側へファイルがうまく受信できていません。もしかしたら、送信側自体がきちんと送信できていないのかもしれません。 以下にそのプログラムの概要と内容を示します。 [概要] 送信側→受信側にUDPを用いて、送信側にあるjpegまたはmpegファイルを送信し、受信側でファイルを開く。 [プログラム概要] ・送信側 ファイルポインタを用いてファイルオープン fread関数とsendto関数を用いて1024バイトずつ送信 ・受信側 ファイルポインタを用いてファイルオープン whileの無限ループ内に、recvfrom関数とfwrite関数を用いて送信側からのデータを受信 [プログラムの内容] ・送信側 printf("読み込み用ファイルを入力して下さい:"); scanf("%s",fname); if((fp = fopen(fname,"rb")) == NULL){ printf("入力ファイルをオープンできない。\n"); exit(1); } char send_buf[1025]; int n; while(n = fread(send_buf,1,1024,fp) != -1){ sendto(theSocket,send_buf,n,0,(LPSOCKADDR)&saServer,sizeof(struct sockaddr)); } ・受信側 char Recv_buf[1025]; char size; SOCKADDR_IN saClient; while(1){ size = recvfrom(theSocket,Recv_buf,1024,0,(LPSOCKADDR)&saClient,&nLen); fwrite(Recv_buf,size,1,fp); } ご指摘またはご教授をいただけたらと思います。 よろしくお願いします。

  • ソケットプログラミングについて

    こんにちは。 以前、この掲示板に質問させていただいた者です。 送信側から受信側へWinsockを利用し、jpeg,mpegファイルを送信したいのですが、プログラムを実行すると強制終了されてしまいます。以下に主要部分を記述します。 [送信側] FILE *fp; char fname[100]; printf("読み込み用ファイルを入力して下さい:"); scanf("%s",fname); if((fp = fopen(fname,"rb")) == NULL){ printf("入力ファイルをオープンできない。\n"); exit(1); } char send_buf[1025]; int nRet; int n; while(n = fread(send_buf,1,1024,fp) != -1){ sendto(theSocket,send_buf,n,0,(LPSOCKADDR)&saServer,sizeof(struct sockaddr)); } fclose(fp); closesocket(theSocket); [受信側] FILE *fp; char fname[100]; printf("書き込み用ファイルを入力して下さい:"); scanf("%s",fname); if((fp = fopen(fname,"wb")) == NULL){ printf("出力ファイルをオープンできない。\n"); exit(1); } char Recv_buf[1025]; char size; SOCKADDR_IN saClient; while(1){ size = recvfrom(theSocket,Recv_buf,1024,0,(LPSOCKADDR)&saClient,&nLen); fwrite(Recv_buf,size,1,fp); } fclose(fp); closesocket(theSocket); 受信側を先に起動し、送信側を起動。送信側で1024バイトずつ送信し、受信側でwhileの無限ループを用いて送信側からのデータを受信するプログラムにしたつもりです。しかし、送信側で読み込みファイルを指定すると強制終了されてしまいます。ファイルオープンの仕方がおかしいのでしょうか?また、上記のプログラムでは1024バイトずつ送信できるようになっていますでしょうか? よろしくお願いします。

  • ソケットプログラミングによるファイル送信について

    VC++.NETを利用して、Winsockにてファイル送信プログラムを作成しています。ソケットはUDPを使用しています。 [行いたいこと] A→B端末へ、1024Byteずつバイナリデータ(画像)を送信。 [現在行っていること(A端末側のプログラムの概略)] 1.ファイルオープン 2.fread関数にてバイナリデータの入力(whileにてループ) 3.A→Bへパケットを1024Byteずつ送信。 #define DATA_SIZE 1024 main{ int n; char send_Buf[DATA_SIZE + 1]; if((fp = fopen(fname,"rb+")) == NULL){ printf("ファイルエラー\n"); exit(1); } //nが0でなくなったら、ループを抜ける。 while((n = fread(send_Buf,1,DATA_SIZE,fp)) != 0) { sendto(s, send_Buf, n, 0, (LPSOCKADDR)&addrin, sizeof(addrin)); } } A側でビルドはできますがエラーが発生して実行できません。 よろしければ教えていただけないでしょうか。C言語の基礎もきちんと出来ていないからなのかもしれません・・・>< よろしくお願いします。

  • ソケット通信で大容量のメールの場合送信されません

    質問です smtpクライアントからtcpでメール送信するプログラムを組んだのですが、 添付ファイルのサイズが大きいもの(500000行を超えるような)を1行ずつsendメソッドで送信すると送信先で受信できません。 400000行まではいくのですが… sendではエラーは返っておらずパケットは送られてる様です。 パケットダンプをとってみたのですが、メールサーバから応答は返ってきていました。 filein.open("test.eml"); if (filein.fail()){ return -1; } if((soc = ConnectHost("testhost","smtp",25)) == -1){ return -1; } send_buf = new char[BUFSIZ]; sprintf(send_buf,"MAIL FROM:<%s>\r\n","test@test.test"); SocketSend(soc,send_buf,strlen(send_buf)); sprintf(send_buf,"RCPT TO:<%s>\r\n","test2@test.test"); SocketSend(soc,send_buf,strlen(send_buf)); sprintf(send_buf,"DATA\r\n"); SocketSend(soc,send_buf,strlen(send_buf)); ss = new char[1024]; while (filein.getline(ss,1024)){ sprintf(send_buf,"%s\r\n",ss); SocketSend(soc,send_buf,strlen(send_buf)); ←ここでループ } delete ss; sprintf(send_buf,"\r\n.\r\n"); SocketSend(soc,send_buf,strlen(send_buf)); SocketRead(soc,send_buf); delete send_buf; filein.close(); if(SocketClose(soc) == -1){ return err; } int SocketSend(int soc,char* buff,int nbytes) { register int nleft,nwritten; char* p = buff; nleft = nbytes; while(nleft > 0) { nwritten = send(soc,p,nleft,0); if(nwritten <= 0){ return nwritten; } nleft -= nwritten; p += nwritten; } return 0; } int SocketClose(int soc) { int ret; if(close(soc) == -1){ return -1; } return 0; } int SocketRead(int soc,char* buff) { int rbyte; rbyte = read(soc,buff,strlen(buff)); return 0; } 上記で問題になっていそうなところがあれば 教えてください。。 よろしくお願いします。

  • ファイルコピープログラムについて

    まだC言語とか始めたばかりであまりよく分からないのですが、 今、ドラッグしたファイルをデスクトップにコピーするプログラムを作成してるのですが、少し困ったことになりました・・・・ 一応ファイルのコピーをデスクトップに作成はできるのですが、 何故か、作成されたファイルのサイズが2バイト程大きくなります・・・。 ファイルサイズを変えずにコピーする方法が分かりません・・・ ソースを張っておきますので、誰か解決策を教えていただけないでしょうか? #include <stdio.h> #include <windows.h> int main(int argc,char *argv[]) { FILE *fp,*copy; int buf; if(argc>1){ rename(argv[1],"DATA.bin"); fp=fopen("DATA.bin","rb"); copy=fopen("c:/xxx/yyy/Desktop/COPY.bin","wb"); while(1){ fread(&buf,sizeof(buf),1,fp); fwrite(&buf,sizeof(buf),1,copy); if(feof(fp)){ puts("OK"); fclose(fp); fclose(copy); rename("DATA.bin",argv[1]); rename("COPY.bin",argv[1]); exit(1); } } } return 0; }

  • FILE オープンについて

    いつもお世話になります。 今ファイルデータ検索処理を検討しております。 今、search.txtには、 検索対象となるファイルパスが記載されています。 [search.txt] /home/hoge/SAMPLE1.jpg /home/hoge/SAMPLE2.jpg search.txtをfopen()し、1行ずつfgets()して、 得られるファイルパスより、そのファイルを fopen()して解析する処理がしたいですが、 fgets()より得られたファイルパスをfopen()し、 fread()するとセグメンテーションエラーになります。 どのようにしたらいいのでしょうか? 現状のコードを下記します。 FILE *fp; char *com1 = "/home/hoge/search.txt"; FILE *confp; char buf1[1024]; char buf2[1024]; int i =0; fp = fopen(com1, "r"); while( fgets(buf1, sizeof(buf1), fp )){ confp = fopen(buf1, "rb"); //*.JPGファイルをオープン //下記fread()でセグメンテーションエラー size_t size = fread( buf2, sizeof(char), 1024, confp ); for( i = 0; i<1024; i++ ){ if( (buf2[i] == 0xff) && (buf2[i+1] == 0xe0) ){ printf("%02x\n",buf[i+5]); } } } fclose(fp); fclose(confp); 上記のように、search.txtをfopen()し、読み込んだファイルパスを fopen()して、fread()読み込みをする方法を 教えて下さい。 どうぞよろしくお願い致します。

  • Officeファイルの送受信

    CSocketを使って、Serverとのネットワークプログラムを 作成していますが、ファイルの送受信が上手く出来ず、困っています。 Server側で指定ファイルデータを読み込み、 Client側でファイルを作成し、オープンすると 中身が壊れていますとメッセージが出てしまいます。 下記は、ファイル送受信のためだけに、 暫定的に組んだソースの抜粋になります。 /* Server側のCAsyncSocket派生クラスのSend関数 -------------- */ int CServerSocket::Send( int nFlags ) { FILE *fp; char *pBuffer; fp = fopen( "C:\\a.doc", "rb" ); /* ファイルサイズを取得する */ long current = ftell( fp ); fseek( fp, 0, SEEK_END ); long size = ftell( fp ); fseek( fp, current, SEEK_SET ); /* ファイルデータ読み込み */ pBuffer = new char[size]; fread( pBuffer, sizeof(char), size, fp ); fclose( fp ); return CAsyncSocket::Send( pBuffer, size, nFlags ); } /* Client側のCSocket派生クラスのOnReceive関数 -------------- */ void CClientSocket::OnReceive( int nErrorCode ) { char aaa[22529]; while ( true ){ n_read = Receive( aaa, 22528 ); received += n_read; if ( received >= 22528 ) break; } Close(); ShutDown(); FILE *fp; fp = fopen( "C:\\test.doc", "wb" ); fwrite( aaa, sizeof(char), 22528, fp ); fclose( fp ); } ※テスト版ということで、Client側では、とりあえず、送信サイズ(ファイルデータサイズ)は  分かっているので、固定にしています。 このような送受信では、Officeファイルの送受信はうまく行かないものなのでしょうか?(ちなみにtxtファイルは上手く行きました)

  • VC++2008Enterpriseでwinsockを扱っていいるので

    VC++2008Enterpriseでwinsockを扱っていいるのですが、 クライアント側(PC)からファイルを読み込んで、ソケットを使って、サーバー側に渡し、何もせず、そのままクライアントに返したものをprintfすると。ファイルの後ろに大量のゴミがくっついて、それの除去ができないのです。 サーバー側では普通に出力できるのですが、何でクライアント側だけ汚いか、よくわからないんです。 送ったファイルはテキストファイルで中身は aaa bbb 111 とこんな感じです。 クライアントのソースは、受信部分を抜粋しますと //ファイルを1行づつ読み込む while((fgets(buffer1, size, fp))!=NULL){ len = strlen(buffer1); sprintf(str,"%4d%s",len,buffer1); //printf("%d行目:バイト数=%s\n%s\n",n,str,buffer1); ok = send(s, str, (int)strlen(str), 0); if(ok==SOCKET_ERROR){ printf("送信できません\n"); exit(1); }else if(ok ==-1){ perror("send"); break; } n++; } shutdown(s,1); while(1){ ok = recv(s, recv_buf, sizeof(recv_buf),0); if(ok == -1) { printf("受信エラー\n"); shutdown(s,2); closesocket(s); break; }else if(ok ==0){ printf("送信終了\n"); shutdown(s,2); closesocket(s); break; }else { printf("%s\n",recv_buf); } } } } これで、出力すると大量のゴミがつくんです。 どなたか、ご指導願い無いでしょうか?

  • ファイルサイズを変更したい

    visualstudio2010を使用しています。 c言語で書いているのですが、 test.txt ←abcdefg ファイルサイズ1KB Wtest.txt←書き込み用ファイル 上記のようなファイルがあり、バイナリでtest.txtを読み込みWtest.txtに書き込みたいと思っています。 その際に、1KBのtest.txtを5KBになるまでバイナリで「abcdefg」の後に0を代入したいのですがどう書けば良いのかわかりません。 FILE *fp, *fpw; char *fname = "test.txt"; char *fname_w = "Wtest.txt"; unsigned char buf[10000]; int size; fp = fopen( fname, "rb" ); if( fp == NULL ){ printf( "%sファイルが開けません\n", fname ); return -1; } fpw = fopen(fname_w, "wb"); if(fpw == NULL){ printf( "%sファイルが開けません\n", fname_w ); return -1; } size = fread( buf, sizeof( unsigned char ), sizeof (fp), fp ); /*ここに処理を追加したい*/ fwrite( buf, sizeof( unsigned char ), size, fpw);

  • どうか、POSTでのファイル転送の仕方を教えてください。

    どうか、POSTでのファイル転送の仕方を教えてください。 borland C++でhttp通信プログラムを書いています。 POSTを使ってhttp通信でファイルをサーバーに転送したいのですが、良く分かりません。 取り合えず、現状としてはwinsockを利用してファイルを転送しようとしました。 (ソース) SOCKET s; [ソケット生成完了] sprintf(send_buf, "POST %s /HTTP1.0\r\n\rHost: %s:%d\r\n", path, host, port); send(s, send_buf, strlen(send_buf), 0); sprinf(send_buf, "\r\n"); send(s, send_buf, strlen(send_buf), 0); ここまでは来たのですが、ここからwhileのfgetsでファイルをバッファにいれてソケットで送信したら、ただのソケット通信になってしまのでここからが分かりません。 この方法であっているのかも、よく分かりません。 http通信でファイルを転送するには、どうすればよいのでしょうか? どなたか、お教え願えませんか?

専門家に質問してみよう