演算増幅器

Similar documents
通信プログラムの試作ーーー UDP を用いたじゃんけんゲームシステム ーーーー裘彬濱 南山大学情報理工学部 ソフトウェア工学科青山研究室

Microsoft Word - Cプログラミング演習(12)

BSDソケットによるIPv6プログラミングを紐解く

第1回 プログラミング演習3 センサーアプリケーション

char int float double の変数型はそれぞれ 文字あるいは小さな整数 整数 実数 より精度の高い ( 数値のより大きい より小さい ) 実数 を扱う時に用いる 備考 : 基本型の説明に示した 浮動小数点 とは数値を指数表現で表す方法である 例えば は指数表現で 3 書く

Microsoft Word - EGX100によるH663通信手引

(1) プログラムの開始場所はいつでも main( ) メソッドから始まる 順番に実行され add( a,b) が実行される これは メソッドを呼び出す ともいう (2)add( ) メソッドに実行が移る この際 add( ) メソッド呼び出し時の a と b の値がそれぞれ add( ) メソッド

PowerPoint プレゼンテーション

Cプログラミング1(再) 第2回

情報ネットワーク演習 2006年10月5日

Microsoft Word - no15.docx

書式に示すように表示したい文字列をダブルクォーテーション (") の間に書けば良い ダブルクォーテーションで囲まれた文字列は 文字列リテラル と呼ばれる プログラム中では以下のように用いる プログラム例 1 printf(" 情報処理基礎 "); printf("c 言語の練習 "); printf

問 2 ( 型変換 ) 次のプログラムを実行しても正しい結果が得られない 何が間違いかを指摘し 正しく修正せよ ただし int サイズが 2 バイト long サイズが 4 バイトの処理系での演算を仮定する #include <stdio.h> int main( void ) { int a =

コマンドラインから受け取った文字列の大文字と小文字を変換するプログラムを作成せよ 入力は 1 バイトの表示文字とし アルファベット文字以外は変換しない 1. #include <stdio.h> 2. #include <ctype.h> /*troupper,islower,isupper,tol

プログラミングI第10回

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

4 実験結果 // 用意されたヘッダファイル #include < stdio.h> #include < fcntl.h> #include < netdb.h> #include < sys/types.h> #include < sys/socket.h> #include < sys/sta

PowerPoint プレゼンテーション

情報処理演習 B8クラス

I. Backus-Naur BNF S + S S * S S x S +, *, x BNF S (parse tree) : * x + x x S * S x + S S S x x (1) * x x * x (2) * + x x x (3) + x * x + x x (4) * *

新・明解C言語 ポインタ完全攻略

PowerPoint プレゼンテーション

プログラミング基礎

Microsoft PowerPoint - C言語の復習(配布用).ppt [互換モード]

Microsoft PowerPoint - 5Chap15.ppt

memo

Microsoft Word - Cプログラミング演習(11)

<4D F736F F D20438CBE8CEA8D758DC F0939A82C282AB2E646F63>

void hash1_init(int *array) int i; for (i = 0; i < HASHSIZE; i++) array[i] = EMPTY; /* i EMPTY */ void hash1_insert(int *array, int n) if (n < 0 n >=

RX ファミリ用 C/C++ コンパイラ V.1.00 Release 02 ご使用上のお願い RX ファミリ用 C/C++ コンパイラの使用上の注意事項 4 件を連絡します #pragma option 使用時の 1 または 2 バイトの整数型の関数戻り値に関する注意事項 (RXC#012) 共用

/*Source.cpp*/ #include<stdio.h> //printf はここでインクルードして初めて使えるようになる // ここで関数 average を定義 3 つの整数の平均値を返す double 型の関数です double average(int a,int b,int c){

PowerPoint プレゼンテーション

プログラミング実習I

£Ã¥×¥í¥°¥é¥ß¥ó¥°ÆþÌç (2018) - Â裶²ó ¨¡ À©¸æ¹½Â¤¡§·«¤êÊÖ¤· ¨¡

PowerPoint プレゼンテーション

画像ファイルを扱う これまでに学んだ条件分岐, 繰り返し, 配列, ファイル入出力を使って, 画像を扱うプログラムにチャレンジしてみよう

演算増幅器

ex14.dvi

Microsoft PowerPoint - program.ppt [互換モード]

:30 12:00 I. I VI II. III. IV. a d V. VI

オペレーティングシステム2003 第2回:

Microsoft PowerPoint - lec10.ppt

Transcription:

ネットワークプログラミングの続き前回はチャットを行うプログラムを作成し ネットワークを利用したプログラミングの基本について学んだ 本日は 前回作成したプログラムを改良していく 具体的には 以下の2つの項目について習っていく ホスト名や IP アドレスの取得の方法 fork() システムコールを使い 子プロセスを作成する方法 チャットプログラムの改良 前回のプログラムを以下のように改良していく 太字部分が変更部分である また 変更の大部 分はサーバープログラムについてであり 以下のような機能を追加している 自分のホスト名と IP アドレスを表示する これは gethostname() と gethostbyname() システムコールを使う 複数のクライアントからのメッセージを表示する これは fork() システムコールを使って 子プロセスを生成して 複数のクライアントに対応する 現在のシステムではサーバープログラムの IP アドレスはローカルループバック (127.0.0.1) になる クライアントプログラム e_client.c #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT 5320 int main(int argc, char *argv[]) int soc; char message[80], ip_address[16]; struct sockaddr_in server; if(argc == 1) printf(" 引数に IP アドレスが必要です \n"); exit(0); strcpy(ip_address, argv[1]); // コマンドライン引数の IP アドレスをコピー soc = socket(pf_inet, SOCK_STREAM, 0); // ソケットの作成 memset((char *)&server, 0, sizeof(server)); // アドレス構造体の初期化 // アドレス構造体のメンバに値を設定 - 1 -

server.sin_family = AF_INET; server.sin_port = htons(port); server.sin_addr.s_addr = inet_addr(ip_address); connect(soc, (struct sockaddr *)&server, sizeof(server)); // メッセージを送る while(1) printf("input message:"); fgets(message, 80, stdin); send(soc, message, strlen(message), 0); if(strncmp(message, "exit", 4) == 0) break; // 接続要求 // この 2 行の順番を // 入れ替え close(soc); return 0; サーバープログラム e_server.c #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/wait.h> #include <unistd.h> #include <signal.h> #include <netdb.h> #define PORT 5320 void kill_zombie_process(int sig); void close_process(int unused); char *show_ip(char *ip_address); int main(void) int soc, acc, size; char buffer[80]; struct sockaddr_in client, server; struct hostent *server_host; pid_t pid; char host_name[257]; int temp; // --- 自ホスト情報の取得と表示 ----- memset(host_name, 0, sizeof(host_name)); gethostname(host_name, 256); server_host = gethostbyname(host_name); // 自ホスト名の取得 // 自ホスト情報の取得 - 2 -

printf("\n-------- informations of server ----------\n"); printf("host name:%s\n", host_name); // 自ホスト名の表示 printf("ip = %s\n", show_ip(server_host->h_addr)); // IP アドレスを表示 printf("\n\n"); // ---------------------------------- soc = socket(pf_inet, SOCK_STREAM, 0); memset((char *)&server, 0, sizeof(server)); // ソケットの作成 // アドレス構造体の初期化 // アドレス構造体のメンバに値を設定 server.sin_family = AF_INET; server.sin_addr.s_addr = htonl(inaddr_any); server.sin_port = htons(port); bind(soc, (struct sockaddr *)&server, sizeof(server)); size = sizeof(client); listen(soc, 5); signal(sigint, close_process); signal(sigchld, kill_zombie_process); // 受け付けるコネクションの最大数を 5 に設定 // [Ctrl]+c を押したとき // 子プロセスの監視 // メッセージを受ける while(1) acc = accept(soc, (struct sockaddr *)&client, &size); pid = fork(); // 接続許可 if(pid == 0) //----- 子プロセス -------------- close(soc); // ソケットをクローズ while(1) memset(buffer, '\0', sizeof(buffer));// 文字列の終わりを示す '\0' で埋める recv(acc, buffer, 80, 0); // データの受信 // クライアントアドレス表示 printf("%s> ", show_ip((char *)&client.sin_addr)); printf("%s", buffer); // 受信データを表示 if(strncmp(buffer, "exit", 4) == 0) break; // "exit" ならば, ループ脱出 close(acc); // ファイルディスクリプタをクローズ exit(0); // 子プロセス終了 else //----- 親プロセス -------------- close(acc); // ファイルディスクリプタをクローズ return 0; - 3 -

// ゾンビプロセスを終了させる void kill_zombie_process(int sig) while(waitpid(-1, NULL, WNOHANG) > 0); signal(sigchld, kill_zombie_process); // [Ctrl]+c が押されたときの処理 ( 子プロセスの終了確認は未対応 ) void close_process(int unused) exit(0); // IP アドレスのポインターを返す char *show_ip(char *ip_address) static char ip[7]; char ipnum[4]; // 静的変数. メモリーから消えない bcopy(ip_address, ipnum, 4); sprintf(ip, "%u.%u.%u.%u", // %u: 符号なし 10 進数 (unsigned char)ipnum[0], (unsigned char)ipnum[1], (unsigned char)ipnum[2], (unsigned char)ipnum[3]); return ip; これらのプログラムについては WEB ページの ネットワークプログラミング を参考にしている URL は http://cai.int-univ.com/sugsi/lecture/netprog/index.html である 自分のホスト名を取得する自分の PC に設定されているホスト名を取得するため gethostname() システムコールを使う これで獲得したホスト名を用いてホスト情報を得るため gethosotbyname() を使う これらの詳細については man コマンドを用いて man gethostname man gethosobyname で調べておくこと 子プロセスの生成マルチプロセスについては教科書 p.308-312 に詳しく書いてある ここでは概要について述べる 実行中のプログラムはプロセスと呼ばれ 一つのプログラム中で複数のプロセスが実行されるものをマルチプロセスと呼ぶ マルチプロセスではプロセスが別のプロセスを呼び出すことで実現され 呼び出すものと呼び出されるものには親子関係で区別される 呼び出す側のプロセスを親プロセスといい 呼び出された側のプロセスを子プロセスという linux(unix) プログラミングではマルチプロセスを実現する fork() システムコールが用意されている fork() を実行すると呼び出した親プロセスとほぼ同様のプロセスがコピーされる 例えば 呼び出す前に変数に代入した値があったとすれば それもコピーされる いくつかの違いもあるが 現状で知っておくべきことは以下である - 4 -

PID( プロセス ID): プロセスを区別する番号 PPID( 親プロセス ID): 自分を呼び出した親プロセスのプロセス ID プロセス ID についてはターミナル上で ps とコマンドを実行すると確認することができる 子プロセスは同じプログラムではあるが データ空間が異なるため 親と子では異なる動作をさせることが出来る 親と子のプロセスの区別は fork() の戻り値で区別できる 親プロセスの場合の fork() の戻り値は子プロセスのプロセス ID であり 正の整数となる 子プロセスについては全て 0 となる 子プロセスの生成に失敗した場合には戻り値が-1 となる 次に簡単な子プロセスを使ったプログラムを示す マルチプロセス用プログラム fork.c #include <stdlib.h> #include <sys/types.h> #include <unistd.h> int sum = 3; int main(void) int pid; pid = fork(); // exit() を使うため // fork() を使うため // fork() を使うため if(pid == 0) // -------- 子プロセス ------------- printf(" 子プロセス \n"); sum += 8; printf(" 合計 = %d\n", sum); else // -------- 親プロセス ------------- printf(" 親プロセス \n"); sum += 3; printf(" 合計 = %d\n", sum); return 0; 出力結果子プロセス合計 = 11 親プロセス合計 = 6 このプログラムではグローバル変数に加算して代入する処理を親 子プロセスそれぞれで行って いる 出力結果は初期値の 3 にそれぞれ加算を行った結果となり グローバル変数も含めて 別の データ空間が用意されていることが確認できる - 5 -

演習クライアントとサーバーのプログラムを実行し 動作を理解しなさい 課題 8 課題 8-1 サーバーのプログラムから自分のホスト名と IP アドレスを表示するプログラムを作成しなさい ただし通信の部分を含め 余計な処理を全て除くこと この場合に必要となるヘッダファイルは以下だけである #include <string.h> #include <unistd.h> #include <netdb.h> 課題 8-2 子プロセスを生成するプログラムにおいて 次の動作を行うプログラムを作成しなさい 親プロセスにおいて 6+2 を計算して 結果を表示 子プロセスにおいて 6-2 を計算して 結果を表示 課題 8-3 gethostbyname() 関数を使って www.akita-nct.jp の IP アドレスを表示するプログ ラムを作成しなさい 参考文献このテキストは以下の文献を参考としました [1] C 言語によるプログラミング応用編第 2 版 内田智史監修 オーム社 - 6 -