システムプログラミング 第13回 プロセス間通信(続き) 情報工学科 篠埜 功.

Slides:



Advertisements
Similar presentations
TCP/IP によるチャットプログラ ム 薄井 秀晃. 基礎知識編 TCP/IP とは? IP とは・・・ Internet Protocol の略称であり通信方法の技術的なルールで あり、実際にデータを送受信する前にデータを小さなデータ に分割し、それに発信元と受信先の IP アドレスを付加させて.
Advertisements

システムプログラミング 情報工学科 篠埜 功 情報工学科 3 年生対象 専門科目 第5回 シェルスクリプトの続 き レポート課題 main 関数の引数 usage メッセージ.
システムプログラミング 第10回 情報工学科 篠埜 功. 今回の内容 プロセス(続き) – execve システムコール 現在のプロセスを、引数に与えられたファイル(実行 形式ファイルあるいはシェルスクリプト等の実行可能 なファイル)を受け取り、現在のプログラムをそれで 置き換える(変身)。 fork.
情報基礎A 情報科学研究科 徳山 豪.
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
Webアプリケーションの 通信メカニズム WEBアプリ研究プロジェクト 第2回.
Ibaraki Univ. Dept of Electrical & Electronic Eng.
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
ネットワークプログラミング 第7回「ネットワークとプログラミング(2)」
システムプログラミング 第5回 情報工学科 篠埜 功 ヒアドキュメント レポート課題 main関数の引数 usageメッセージ
システムプログラミング 第13回 情報工学科 篠埜 功.
システムプログラミング 第11回 シグナル 情報工学科  篠埜 功.
OSとコマンド OS:コンピュータを使うための基本プログラム コマンド:OS上で使用できる命令 OS本体であるカーネルの内部コマンド
Windows Network Programming
担当:青木義満 情報工学科 3年生対象 専門科目 システムプログラミング システムプログラミング プロセス間通信(パイプ) 担当:青木義満
TCPソケットプログラミング ソケットプログラミング TCP-echoのデータ通信手順
HTTPプロトコルとJSP (1) データベース論 第3回.
HTTPプロトコル J2EE I 第7回 /
担当:青木義満、篠埜 功 情報工学科 3年生対象 専門科目 システムプログラミング 第8回、第9回 シグナル処理 担当:青木義満、篠埜 功
システムプログラミング 第11回 シグナル 情報工学科  篠埜 功.
担当:青木義満 情報工学科 3年生対象 専門科目 システムプログラミング 第11回 プロセス間通信4 仮想FTPの実現 担当:青木義満
情報コミュニケーション入門 総合実習(1) 基礎知識のポイント(2)
第5回ネットワークプログラミング 中村 修.
情報工学科 3年生対象 専門科目 システムプログラミング 第5回、第6回 ヒアドキュメント レポート課題 情報工学科 篠埜 功.
情報コミュニケーション入門b 第10回 Web入門(1)
情報コミュニケーション入門b 第10回 Web入門(1)
第11回ネットワークプログラミング 中村 修.
第7回ネットワークプログラミング 中村 修.
UDPエコーサーバ UDP-echoサーバのプログラムモデル(Cプログラム) サーバで利用するソケット関数(Cプログラム)
システムプログラミング 第13回 情報工学科 篠埜 功.
ソケットプログラム(TCP,UDP) EasyChat開発
システムプログラミング 第9回 、10回 ハードリンク、シンボリックリンク プロセスの生成
システムプログラミング 第12回 プロセス間通信 情報工学科 篠埜 功.
岡村耕二 トランスポート層 岡村耕二 情報ネットワーク.
岡村耕二 トランスポート層 ソケットプログラミング 岡村耕二 情報ネットワーク.
岡村耕二 トランスポート層 岡村耕二 情報ネットワーク.
インターネットにおける真に プライベートなネットワークの構築
ユビキタスシステムアーキテクチャ 第5回 ネットワークプログラミングの基礎
情報コミュニケーション入門e 第11回 Part2 Web入門(1)
Ibaraki Univ. Dept of Electrical & Electronic Eng.
Webプロキシ HTTP1.0 ヒント CS-B3 ネットワークプログラミング  &情報科学科実験I.
TCP/IPとプロセス間通信 2007年1月12日 海谷 治彦.
岡村耕二 トランスポート層 岡村耕二 情報ネットワーク.
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
岡村耕二 トランスポート層 岡村耕二 情報ネットワーク.
配列変数とポインタ 静的確保と動的確保 ポインタ配列 2次元配列 時間計測 第1回レポートの課題
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
システムプログラミング 第12回 プロセス間通信 情報工学科 篠埜 功.
システムプログラミング 第6回 システムコールのエラーメッセージ ファイルシステム 情報工学科 篠埜 功.
担当:青木義満 情報工学科 3年生対象 専門科目 システムプログラミング 第12回 システムプログラミング 反復サーバと並行サーバ 担当:青木義満
システムプログラミング 第12回 プロセス間通信 情報工学科 篠埜 功.
ネットワーク・プログラミング デバイスドライバと環境変数.
システムプログラミング 第10回 プロセス間通信3 簡易Web server(準備) Chat プログラム 担当:青木義満、篠埜 功
岡村耕二 TCP通信プログラム 岡村耕二 情報ネットワーク.
ネットワークプロトコル.
担当:青木義満 情報工学科 3年生対象 専門科目 システムプログラミング 第11回 プロセス間通信4 仮想FTPの実現 担当:青木義満
システムプログラミング 第9回 、10回 ハードリンク、シンボリックリンク プロセスの生成
ネットワーク・プログラミング TCPサーバ.
情報工学科 3年生対象 専門科目 システムプログラミング 第3回 makeコマンド 動的リンクライブラリ 情報工学科 篠埜 功.
情報工学科 3年生対象 専門科目 システムプログラミング 第3回 makeコマンド 動的リンクライブラリ 情報工学科 篠埜 功.
ネットワーク・プログラミング 1対多のプロセス間通信.
岡村耕二 UDP通信プログラム 課題と回答例 岡村耕二 情報ネットワーク.
システムプログラミング 第11回 シグナル 情報工学科  篠埜 功.
アプリケーションゲートウェイ実験 2001.10.5 鬼塚 優.
ネットワーク・プログラミング マルチタスク.
SMTPプロトコル 2001年8月7日 龍 浩志.
TCP/IPの通信手順 (tcpdump)
ポートスキャン実習 2002年9月19日 修士1年 兼子 譲 牧之内研究室「インターネット実習」Webページ
岡村耕二 TCP通信プログラム 岡村耕二 情報ネットワーク.
HTTPプロトコルの詳細 M1 峯 肇史.
Presentation transcript:

システムプログラミング 第13回 プロセス間通信(続き) 情報工学科 篠埜 功

ソケットの種類 ストリームソケット バーチャルサーキット(コネクション型通信)で実現されている 通信相手に対してコネクションを設定 コネクションに対してデータ送受信 終了後,コネクションを解除 → 例)電話 特定のプロセス間でデータを継続的に送る通信 リンク設定のオーバーヘッド 通信の信頼性が保証される(データ順序,内容) コネクション型プロトコル: TCP(Transmission Control Protocol)

ソケットの種類 データグラムソケット データグラム(コネクションレス型通信)で実現されている コネクションを設定せず,ネットワーク層(第3層)の機能を用いる 個々のデータをその都度通信相手へ送る コネクションレス型通信 (例)手紙(相手の住所をその都度指定) 複数のプロセス間で小さなデータを断続的に送る通信 リンク設定のオーバーヘッドないが,その都度相手先を指定 通信の信頼性が保証されていない(データ順序,内容) コネクションレス型プロトコル: UDP(User datagram Protocol)

クライアントサーバシステム クライアントとサーバ 複数のプロセスがプロセス間通信機能を使って処理を進める サービスの処理要求を出す側:クライアントプロセス サービスの処理提供する側:サーバプロセス

クライアント・サーバシステム

サーバの運用形態 反復サーバ サーバプロセス自身が順次クライアントの要求を処理するサーバ形態

サーバの運用形態 並行サーバ サーバプロセスが複数の子プロセスを生成し,並行して処理を行うサーバ形態

例 inet_server.c, inet_client.c インターネット上にある2つのマシン上のプロセス間で、メッセージのやりとりを行うプログラム。 IP addressとポート番号でプロセスを識別。 8行目と9行目のSERVER_PORTは、 50000 + 学籍番号の下4桁に修正。 inet_clientの第一引数に通信相手をホスト名(IP addressに対応、hostnameコマンドで確認)で指定。ポート番号はプログラム中の、SERVER_PORTの番号で指定。 自分で通信ができた人は、近くの人と通信を試す。 他人と通信する場合はSERVER_PORT番号を同じにする。(どちらかに合わせる)

サーバプログラム #include <arpa/inet.h> const int one = 1; #include <unistd.h> #include <stdlib.h> #include <string.h> #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define BUFSIZE 256 #define SERVER_PORT 50000 /* 50000+学籍番号下4桁 */ int main(int argc, char *argv[]) { int sockfd; int ns; struct sockaddr_in server; struct sockaddr_in client; socklen_t fromlen; char buf[BUFSIZE]; int msglen; const int one = 1; if(argc != 2){ fprintf(stderr, "Usage: %s message(StoC)\n", argv[0]); exit(1); }

if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { perror("server: socket"); exit(1); } bzero((char *)&server, sizeof(server)); server.sin_family = PF_INET; server.sin_port = htons(SERVER_PORT); server.sin_addr.s_addr = htonl(INADDR_ANY); setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int)); if(bind(sockfd, (struct sockaddr *)&server, sizeof(server)) == -1) { perror("server: bind"); if(listen(sockfd, 5) == -1){ perror("server: listen"); INADDR_ANYを指定するのは、自分がIP addressを1つだけしか持っていない場合。Network cardが2枚あるPCでは2つのIP addressがあり、この場合は明示的に指定する。

fromlen = sizeof(client); if((ns = accept(sockfd, (struct sockaddr *)&client, &fromlen)) == -1){ perror("server: accept"); exit(1); } printf("\nconnect request from: %s port: %d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); if(read(ns, buf, BUFSIZE) == -1){ perror("server: read"); printf("\n<SERVER> message from client : %s\n",buf); msglen = strlen(argv[1]) + 1; if(write(ns, argv[1], msglen) == -1){ perror("server: write"); close(ns); close(sockfd); exit(0); }

クライアントプログラム #include <unistd.h> #include <stdlib.h> #include <string.h> #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #define BUFSIZE 256 #define SERVER_PORT 50000 /* 50000+学籍番号下4桁にする */ int main(int argc, char *argv[]) { int sockfd; struct sockaddr_in server; struct hostent *hp; char buf[BUFSIZE]; int msglen;

if(argc != 3){ fprintf(stderr, "Usage: %s server-hostname message(CtoS)\n“, argv[0]); exit(1); } if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1){ perror("client: socket"); bzero((char *)&server, sizeof(server)); server.sin_family = PF_INET; server.sin_port = htons(SERVER_PORT); if((hp = gethostbyname(argv[1])) == NULL){ herror("client: gethostbyname"); bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length);

if(connect(sockfd, (struct sockaddr *)&server, sizeof(server)) == -1){ perror("client: connect"); exit(1); } msglen = strlen(argv[2]) + 1; if(write(sockfd, argv[2], msglen) == -1){ perror("client: write"); } if(read(sockfd, buf, BUFSIZE) == -1){ perror("client: read"); printf("\n<CLIENT> message from server : %s\n\n", buf); close(sockfd); exit(0);

簡易web server プログラム inet_server.cを修正して作成したもの。 accept及びread, writeをfor loopで繰り返す。 反復サーバ方式 クライアント(ブラウザ等)からのメッセージ GET /index.html HTTP/1.0 (1行目) 2行目以降は各種情報 応答メッセージ HTTP/1.0 200等(1行目)で応答の種別、2行目から各種情報の後、ファイル本体を送る。

簡易web server プログラム 実行手順 $ gcc –o web_server0 web_server0.c $ ./web_server0 test.html (web_server0を実行するディレクトリにtest.htmlを置いておく) その後、ブラウザで、 http://oli005.sic.shibaura-it.ac.jp:50000/aaa.html などを入力する。 :のあとに、web_server0.cで指定したweb serverのポート番号を入れる(50000+学籍番号の下4桁)。ホスト名部分はwebサーバーを起動するホスト上でhostnameコマンドで確認する。 $ hostname oli005.sic.shibaura-it.ac.jp など。今はファイル名はサーバ側で決め打ちなので、ブラウザに入れるファイル名は何でもよい。

簡易web server #include <stdlib.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/stat.h> #include <netinet/in.h> #include <signal.h> #define BUFSIZE 1024 #define SERVER_PORT 50000 /* サーバのソケットの名前(ポート番号) 各自、50000+自分の学籍番号に変更 */

続き 200はステータスコードであり、正常終了を表す。 int main(int argc, char *argv[]) { int sockfd; int ns; int i; struct sockaddr_in server; struct sockaddr_in client; socklen_t fromlen; char buf[BUFSIZE]; char readbuf [BUFSIZE]; const int one = 1; int readbyte; FILE *file; char * responce1 = "HTTP/1.0 200\r\n"; char * responce2 = "Content-type: text/html\r\n"; char * newLine = "\r\n"; 200はステータスコードであり、正常終了を表す。

続き if (argc != 2){ fprintf(stderr,"Usage: %s filename\n", argv[0] ); exit(1); } if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { perror("server: socket"); bzero((char *)&server, sizeof(server)); server.sin_family = PF_INET; server.sin_port = htons(SERVER_PORT); /* ソケットの名前(ポート番号)の設定 */ server.sin_addr.s_addr = htonl(INADDR_ANY); /* IPアドレスの設定 */ setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));

続き if (bind (sockfd, (struct sockaddr *)&server, sizeof(server)) == -1) { perror("server: bind"); exit(1); } if (listen(sockfd, 5) == -1) { perror("server: listen"); for (i=1;;i++) { printf ("Waiting request from client (%d)\n",i); fromlen = sizeof(client); if ((ns = accept(sockfd, (struct sockaddr *)&client, &fromlen)) == -1 ){ perror("server: accept"); clientには、接続してきたclientの情報が格納される

/* クライアントプロセスのソケットアドレス情報の確認 */ printf("\nconnect request from: %s port: %d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); if (read(ns, buf, BUFSIZE) == -1 ) { perror("server: read"); exit(1); } printf("\n<SERVER> message from client : %s\n",buf); write (ns,responce1,strlen(responce1)); write (ns,responce2,strlen(responce2)); write (ns,newLine, strlen(newLine)); file = fopen (argv[1], "r"); if (file) { while ((readbyte = read (fileno(file), readbuf, BUFSIZE))>0) { if (write (ns, readbuf, readbyte) == -1) { perror ("failed to write to socket"); fclose(file); } close(ns);

レポート課題5 web_server0.cでは、送るファイルをサーバー起動時の引数に与えていたが、クライアントで指定したファイル(サーバ起動ディレクトリ等、自分で決めたディレクトリからの相対path)が存在する場合にそれを送り返すプログラムに拡張せよ。存在しない場合、ステータスコードを404として、The requested file … was not found on this server. のようなメッセージを本文に含むHTMLを送り返せ。 メソッドは、GETだけが送られてくると仮定してよい。(実際は他にもメソッドがあるが。) 具体的には、sscanf (buf, “GET /%s ”, path); のような感じでよい。

レポートの提出方法 □ 下記のファイルを作成し、提出 kadai5.c, kadai5.txt □ 提出方法 システムプログラミング講義用の課題提出用フォルダ内にあるkadai5というフォルダの中に自分の学籍番号を名前とするフォルダを作成し、その中に上記ファイルを置く。kadai5.txt内に学籍番号、氏名、日付、および作成したプログラムの簡単な説明を記載する。 □ 提出期限   1月24日の23:59まで。締め切り後に提出した場合、成績への反映を保証しない。

補足 inet_server.cではBUFSIZEが256だったが、足りないので(とりあえず)1024にしている。GETメソッドの引数の長さは制限がない。現状のプログラムでは長いURLには対応できない。通常のweb serverでは何らかの上限値を設定することにより対処する。 accept及びread, writeをfor loopで繰り返す。 反復サーバ方式 クライアント(ブラウザ等)からのメッセージ 1行目は、GET /index.html HTTP/1.0 など。(index.html部分はブラウザの入力によって変わる。HTTP/1.0の部分はクライアントのHTTPのversionであり、HTTP/1.1が主流。) 2行目以降は各種情報 応答メッセージ HTTP/1.0 200等(1行目)でサーバーのHTTPのversionおよびステータスコード、2行目から各種情報を何行か入れた後、空行(CR+LF)を一行入れ、ファイルを送る場合は送る。200は正常に処理したことを表すステータスコードである。

補足 Content-Typeは、text/html(htmlファイル)に決め打ちしている。 実際のweb serverでは、個人のアカウントではなく、web server用のアカウントを作成し、そのアカウントで起動することが普通。(otherのreadが許可されていなければそのファイルはweb serverは読めないことになる。) 要求されたファイルがない場合はステータスコード404(ファイルがサーバ上にないことを表す)を返してその処理を終える。(web serverは終了させない。) 詳しくはHTTPプロトコルの定義を参照(本講義の範囲外) serverを起動すると、学内からアクセスが可能な状態になるので、見られては困るファイルが他人に取得されることがないよう注意する。(実験が終わったらサーバを終了させる。)

補足: Internet Explorerの エラーメッセージ表示について webサーバがステータスコード404を返した場合、 browserがInternet Explorerの場合は、「HTTPエラーメッセージを簡易表示する」 という機能があり、この機能がONになっていると、Internet Explorer独自のエラーページが表示されます。この機能はON-OFFの設定が可能で、「ツール」 -> 「インターネットオプション」 -> 「詳細設定」 -> 「HTTPエラーメッセージを簡易表示する」の順でたどれます。これをOFFにするとサーバが送ったエラーページが表示されるはずです。

補足: エラーメッセージの送り方の例 (例1) web serverプログラム中にエラーメッセージのHTMLを文字列で直書きしておき、それをclientに送る。 (例2) エラーメッセージのHTMLをあらかじめ何らかのファイル(error.htmlなど)に書いておき、それをweb serverプログラム中で読み込んでclientに送る。