【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※返信付き投稿の削除は禁止!
 ※マルチポスト(多重投稿)は慎んで!

 詳しくはこちら


本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール掲示板2こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.22373

ソケットを使用してのバイナリファイル送信
投稿者---socket(2005/08/02 19:52:41)


現在ソケット(TCP)を使ってファイルの送信をするプログラムを
作成しています。
なお、下記ソースは、Windows VC++でビルドして、実行しております。
#IPアドレスは、セキュリティの為、隠してあります。

テキストファイルは問題なく送信できるのは、確認できたのですが、
全てのバイナリファイルではないのですが、途中でEOF(0)を
認識してしまい、最後まで送信出来ない事がありました。

この対応方法をご教授頂ければ幸いです。
何卒宜しくお願いします。

○実行方法
クライアント側、サーバ側それぞれをVCでビルド。
#client.cのIPアドレスにserver.cを実行したIPアドレスを設定。
#各々wsock32.libをオブジェクト/ライブラリモジュールに追加。

サーバ側から実行し、その後、クライアント側も実行。
接続が確立したら
InputMessage:と聞かれるので、適当に入力。
その後、ファイルが送受信。
終了後は、file_uketoriに受信したい内容が入っている(ハズ)


---クライアント側(client.c)----
#include <stdio.h>
#include <io.h>
#include <winsock.h>
char message[1024];
main()
{

int sock, i;

struct sockaddr_in sinhim;
short port=10001;
char *IPaddress="---.---.--.--";

unsigned int len, len2;
char uketori[1024];

FILE *fp;

WSADATA wsaData;
WSAStartup(MAKEWORD(1, 1), &wsaData);

//アドレス情報の設定
sinhim.sin_family = AF_INET;
sinhim.sin_port = htons(port);//ポート番号の指定
sinhim.sin_addr.s_addr = inet_addr(IPaddress);//宛先指定

//ソケット生成TCP

sock=socket(AF_INET, SOCK_STREAM, 0 );

//サーバへの接続処理
if(connect(sock,(struct sockaddr *)&sinhim, sizeof(sinhim) ) < 0)
    printf("Can't connect.\n");
else
printf("Connected.\n");

//データの読込(Please file!)
printf("Input Message:");
gets(message);
send(sock,message,strlen(message)+1,0);

if ((fp=fopen("file_uketori","wb"))==NULL)
   printf("not file\n");

//ファイルを受け取る

while(1){
len=recv(sock,uketori,1024,0);
uketori[len] = '\0';
printf("%d\n", len);

if ( len == 0 || len == -1)break;
fprintf(fp, "%s", uketori);
}

fclose(fp);
close(sock);//切断処理
}



---サーバ側(server.c)----
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <winsock.h>
char message[1024];
#include <string.h>

main()
{
int sock, sock2;
struct sockaddr_in sinme;
struct sockaddr_in from;
int len=sizeof(from);
int one=1;
int t;

int len2;
char buf[1024];
int read_fd ;

short port=10001;

WSADATA wsaData;
WSAStartup(MAKEWORD(1, 1), &wsaData);


sinme.sin_family = AF_INET;
sinme.sin_port = htons(port); 
sinme.sin_addr.s_addr = htonl(INADDR_ANY);

sock=socket(AF_INET, SOCK_STREAM, 0 );


if(bind(sock, (struct sockaddr *)&sinme, sizeof(sinme)) <0)
printf("Can't bind.\n");
listen(sock,SOMAXCONN);


printf("Waiting for Connection Request.\n");
sock2=accept(sock, (struct sockaddr *)&from, &len);
if(sock2 < 0 ){
printf("Can't accepted.\n");
exit(0);
}
else{
printf("Connected from %s.\n",inet_ntoa(from.sin_addr));
}

recv(sock2, message, 1024,0);
printf("Received Message=%s\n",message);

//ファイルの読み込み、書き込み
read_fd = open("binary_file", O_RDONLY|O_BINARY);

 while(1){
   len2 = read(read_fd, buf, 1024);
   printf("%d\n", len2);

   if(len2 <= 0){
     printf("finish send file\n");
     break;
   }
   else{
     send(sock2, buf, len2,0);
   }
 }
 
close(read_fd);

printf("finish\n");
close(sock);

 t = GetTickCount();

printf("time = %d\n",t);
printf("データ受信開始から %d日 %d時間 %d分 %d秒 経過",t/86400000,(t/3600000)%24,(t/60000)%60,(t/1000)%60);

}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:ソケットを使用してのバイナリファイル送信 22374 REE 2005/08/02 20:15:02


No.22374

Re:ソケットを使用してのバイナリファイル送信
投稿者---REE(2005/08/02 20:15:02)


受信側でfprintfを使っていますが、これはテキスト用の関数です。
バイナリの場合には、fwriteを使用します。



この投稿にコメントする

削除パスワード

No.22386

ソケットを使用してのバイナリファイル送信(2)
投稿者---socket(2005/08/03 11:55:27)


REEさん
お早いお返事ありがとうございました。

>受信側でfprintfを使っていますが、これはテキスト用の関数です。
>バイナリの場合には、fwriteを使用します。

早速ご指摘どおりにfprintfの箇所を
fwrite(uketori,sizeof(char),len,fp);
にして実行したところうまくできました。

試しにfwriteでテキストファイルも送受信した所
うまくできました。

fwriteでテキスト、バイナリファイルどちらも
送受信できたのですが、
やはり使い分けた方がいいのでしょうか?


この投稿にコメントする

削除パスワード

No.22393

Re:ソケットを使用してのバイナリファイル送信(2)
投稿者---YuO(2005/08/03 13:03:23)


>fwriteでテキスト、バイナリファイルどちらも
>送受信できたのですが、
>やはり使い分けた方がいいのでしょうか?

テキストファイルというのは,バイナリファイルの一種です。
# ファイルは全てバイナリファイルとして扱える。

バイト列を扱うならfwrite/fread,
文字列を扱うならfgets/fprintf,
という使い分けになるかと思います。
# バイナリでも文字列を扱うならfprintfは有用。

今回の場合,ファイルの中身を扱うわけではないですから,
単にバイナリファイルとして読み書きすればよいです。



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧