Upload
rozene
View
41
Download
0
Embed Size (px)
DESCRIPTION
ソケット及び TCP/IP を用いた ネットワークプログラミングの基礎. 平成 18 年 4 月 17 日 B5 小池 和洋. テキストファイルの転送. サンプル プログラム 小文字を大文字へ変換. 1. クライアントから小文字を含んだ文字列を送信 2. サーバからの応答. “ abCde ”. クライアント. サーバ. “ ABCDE ”. テキストファイルの転送. サンプルプログラムの改良. 1.指定したテキストファイルの中身を読み出す。 2.該当するファイルがない場合はエラーを返す。 3.複数のクライアントからの要求を - PowerPoint PPT Presentation
Citation preview
ソケット及びソケット及び TCP/IPTCP/IP を用いたを用いたネットワークプログラミングのネットワークプログラミングの
基礎基礎
平成平成 1818 年年 44 月月 1717 日日B5B5 小池 和洋 小池 和洋
テキストファイルの転送テキストファイルの転送► サンプル プログラムサンプル プログラム
小文字を大文字へ変換小文字を大文字へ変換
クライアント サーバ
“abCde”
“ABCDE”
1. クライアントから小文字を含んだ文字列を送信2. サーバからの応答
テキストファイルの転送テキストファイルの転送► サンプルプログラムの改良サンプルプログラムの改良
1.指定したテキストファイルの中身を読み出す。
2.該当するファイルがない場合はエラーを返す。
3.複数のクライアントからの要求を 受け入れられるようにする。
テキストファイルを読み出すテキストファイルを読み出す
クライアント サーバ
“test.txt”
1. クライアントからファイル名を送信2. 該当するファイルを読み出す3. ファイルの内容を送り返す
abcdetest.txt
abcde
サンプルからの変更(サーバ)サンプルからの変更(サーバ)main() {
・・・/* クライアントからの接続を待つ */
if ((client_fd=…) {・・・
}
/* クライアントとのデータのやり取り */
while ((n = …) {・・・
}close(client_fd);close(fd);return 0;
}
main() {・・・while(1) {
parent(fd);}
close(fd);return 0;
}
int parent(int fd) {
}int child(int client_fd) {
}
関数 parent として定義
関数 child として定義
無限ループ
サーバサーバ► 親プロセス親プロセスint parent(int fd){
int client_fd;
/* クライアントからの接続を待つ */if ((client_fd = accept(fd, NULL, NULL) < 0) {
perror(“accept”);close(fd);return 1;
}
/* fork による子への引渡し */if (fork() == 0) {
child(client_fd);}return 0;
}
fork() = 0 なら子プロセスを作りあとの作業をさせる
この部分はmain がそのまま入っている
親は main に戻り、応答を待つ( while によるループ)
►子プロセス子プロセスint child(int client_fd){
char buf[1024], ch;int n, i;FILE *fp;
/* クライアントとのデータのやり取り */while (n = read(client_fd, buf, sizeof(buf)-1)) > 0) { buf[n] = ‘\0’; printf(“file: ‘%s’\n”, buf);
/* 指定されたファイルがなければエラーを返す */ if ((fp = fopen(buf, “r”)) == NULL) { fprintf(stderr, “file open error!\n”); /* サーバ側にも表示 */ sprintf(buf, “file open error!”, client_fd); write(client_fd, buf, strlen(buf)); return 1; } printf(“return to client:\n%s\n”, buf); write(client_fd, buf, sizeof(buf)-1); fclose(fp);}
/* 終了 */ close(client_fd); return 0;}
指定されたファイルを読み出す
ファイルがなければエラー表示
ファイルの中身を送る
サンプルからの変更(クライアサンプルからの変更(クライアント)ント)main() {
FILE *fp;char fname[64]; /* ファイル名 */
・・・/* サーバとのデータのやり取り */
if (fgets(buf, sizeof(buf), stdin) == NULL) {・・・
}buf[strlen(buf)-1] = ‘\0’; /* 改行文字を消す */
printf(“send to server: ‘%s’\n”, buf);write(fd, buf, strlen(buf)); /* 送信 */
新たに定義
サンプルからの変更(クライアサンプルからの変更(クライアント)ント)main() {
FILE *fp;char fname[64]; /* ファイル名 */
・・・/* サーバとのデータのやり取り */
if (fgets(fname, sizeof(fname), stdin) == NULL) {・・・
}fname[strlen(fname)-1] = ‘\0’; /* 改行文字を消す */
printf(“send to server: ‘%s’\n”, fname);write(fd, fname, strlen(fname)); /* ファイル名の送信 */
クライアントクライアント if (n = read(fd, buf, sizeof(buf)-1)) < 0) { perror(“read”); close(fd); return 1; }
if (strcmp(buf, “file open error!”) == 0) { fprintf(stderr, “%s\n”, buf) close(fd); return 0; }
ファイルがなければfile open error!と返ってくる
/* サーバの子プロセス */if ((fp = fopen(buf, “r”)) == NULL) { fprintf(stderr, “file open error!\n”); /* サーバ側にも表示 */ sprintf(buf, “file open error!”, client_fd); write(client_fd, buf, strlen(buf)); return 1;}
サーバから返ってきた文字列をbuf に読み込む
クライアントクライアント fp = fopen(fname, “w”);
fprintf(fp, “%s”, buf); buf[strlen(buf)-1] = ‘\0’; printf(“-----received fron server:\n%s\n-----\n”, buf);
/* 終了 */
fclose(fp); close(fd); return 0;}
ファイルへの書き込み
受け取ったテキストの中身を画面にも表示される
実行結果実行結果► サーバ側サーバ側 ► クライアント側クライアント側
ファイル名指定
課題課題►どんなサイズのファイルでも読み込めるようどんなサイズのファイルでも読み込めるよう
にに2,3行程度のファイルもあれば、何千行も書かれたファイルも2,3行程度のファイルもあれば、何千行も書かれたファイルも
ある。ある。11 行ずつ、又は行ずつ、又は 11 文字ずつ読み込むように改良したい。文字ずつ読み込むように改良したい。
►サーバの終了方法を工夫するサーバの終了方法を工夫する今は今は Ctrl+CCtrl+C で終わるようになっているが、他の終わり方にしたい。で終わるようになっているが、他の終わり方にしたい。
►バイナリファイルにも適応できるようにするバイナリファイルにも適応できるようにする