ネットワークプログラミング 第 9 回「...

47
ネネネネネネネネネネネネネ ネ9ネネネネネネネネネネネネネネネネ#9 Applied Network Programming (last lecture!) 20 10 ネネネネ Rodney Van Meter

Upload: casey

Post on 20-Jan-2016

30 views

Category:

Documents


2 download

DESCRIPTION

20 10 年秋学期 Rodney Van Meter. ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming (last lecture!). 今期の授業スケジュール(予定). 第1回 9/28 : Introduction / イントロダクション 第2回 10/5 : C Basics ~ Functions, Variables, Data Types ・ Makefiles - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

ネットワークプログラミング第 9回「応用ネットワークプログラミング」#9 Applied Network Programming (last lecture!)

20 10年秋学期Rodney Van Meter

Page 2: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

今期の授業スケジュール(予定) 第1回 9/28 : Introduction / イントロダクション 第2回 10/5: C Basics~ Functions, Variables, Data

Types・Makefiles 第3回 10/12: C Basics~ Command Line Arguments

・ Structures ・ Pointers 第4回 10/19: C Basics~ Pointers & Arrays ・ Lists 第5回 10/26 : file I/O ・ Network Protocols 第6回 11/2 : Network Programming (1) 第7回 11/9 : Network Programming (2) 第8回 11/16 : Network Programming ( 3) 11/23: No class! ORF! Please come! 第9回 11/30 : Applied Network Programming 第10回 12/7 : Work on Projects 第11回 12/14 : Mid-Term Presentation (light!) 第1 2 回 12/21 : Work on Projects 第13回 1/11 : Final Presentations!!!

Page 3: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

中間発表 (Mid-term Presentation)

Problem (or project) definition (Related work) Key idea How you will evaluate it Schedule

NOT 実装、評価、論文執筆 !

Page 4: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

ミニプロの中間発表について (2)

Team members Division of responsibility How you will work together

What programming environment? What source code control (svn, cvs,

rcs...?) Plan for APIs, functional definition Testing plan

Page 5: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

Submission of Final Project Source code, a presentation, and a

report Source must be commented

日本語 or 英語 (eigo) Report contents

What you made How you made it Why it’s cool/what problem it solves Execution environment

Page 6: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

ミニプロの提出 提出は、ソースコードならびにレポート

提出ソースコードにはコメントを付加 日本語 or 英語

レポートには以下の項目を含める 何を作ったのか 使用方法 面白さ 実行環境

Page 7: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

Today, we fork() 講義

前回のおさらい TCP-server

listen() accept()

forkサーバの挙動プロセス練習 1 : forkに慣れよう実習:平行サーバを作成

Page 8: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

TCP 通信の流れ (server)socket()

bind()

listen()

accept()

socket()

connect()

read()

close()

TCP client

TCP Server

write()read()

write()

read()

close()

data

data

establish

end

Page 9: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

fork

Page 10: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

Common Server Structure

Server

Client

Client

Client クライアント

クライアント

クライアント

集中!

複数のクライアントから同時にアクセスを受ける

Multiple clients accessingserver at the same time

Page 11: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

Let’s Feel Like a Server

Lots of sockets, lots of clients is hard! Have to examine one by one

たくさんのソケットを扱ったり,めんどくさいことはしたくない いちいちソケットを検査するのが面倒 どれにどれだけ時間がかけられるんだ?

沢山のクライアントが接続してきたら,大変

Page 12: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

自分の分身を作ればいいんだ!

t

親プロセス

子プロセス二号

子プロセス一号

仕事は全部,分身にまかせよう 親の仕事は,コネクションがきたときに分身を作ることだけ

Page 13: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

平行処理 (concurrent processing) 素早い応答 多くの要求を処理

C1

C2

C3 C4

server

connect()read()write()

listen()accept()fork()

recv()send()C1:process

C2

C3

C4

Page 14: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

Function for creating a child

fork system call int fork(); Makes an exact copy of the process How do you tell difference between

parent and child? fork()’s return value: 0 for the child Integer >0 is child pid -1 is error

Page 15: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

プロセスを見る Linux系 (ccx00)

% ps aux Solaris 又は Linux

% ps -efj BSD系又は Linux

% ps auxj

USER PID PPID PGID …………… COMMANDnobody 123 89 89 …………… httpd

Page 16: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

プログラムの実行とプロセス

main(int argc, char *argv){ struct sockaddr_in me, peer; ……. if(pid = fork()) == 0) {

child process. } else if(pid > 0) {

parenet process. } else {

error process. }}

プログラム

OS

実行

プロセス

生成

プログラム

fork()

プロセス

生成

}

プログラム

親プロセス 子プロセス

コピー・・・・・・・・・・・・・・・・・・・・・・・・・・・

・・・・・・・・・・・・・・・・・・・・・・・・・・・

Page 17: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

親と子の区別 fork()の返り値Distinguishing Parent & Child

int childpid;childpid = fork();

親側 子側

if(childpid > 0){ 親の処理 ;}

else if(childpid == 0){ 子の処理}

Page 18: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

Common Server Processing Servers (telnet, ssh, ftpなど ) with

long individual connections 接続要求があったら, acceptして,とりあえず fork(); 子プロセスだったら、サービスの提供開始 親プロセスだったら、接続要求待ち

Don’t have to deal w/ lots of sockets in one process

Page 19: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

Multi-client server using fork()

Client 1Client 1

クライアント 2クライアント 2

クライアント 3クライアント 3

ServerServer

Server waiting at listen()

File descriptor

Page 20: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

fork()を用いたマルチクライアントサーバの仕組み

クライアント 1クライアント 1

クライアント 2クライアント 2

クライアント 3クライアント 3

サーバサーバ

Request comes from client(right before accept())

リクエスト

ファイルディスクリプタ

Page 21: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

fork()を用いたマルチクライアントサーバの仕組み

クライアント 1クライアント 1

クライアント 2クライアント 2

クライアント 3クライアント 3

サーバ (親 )サーバ )親 (

Parent closes its client socket,goes back to accept()Client closes its listen()ing socket

ファイルディスクリプタ

サーバ (子 )サーバ )子 (

Page 22: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

fork()を用いたマルチクライアントサーバの仕組み

クライアント 1クライアント 1

クライアント 2クライアント 2

クライアント 3クライアント 3

サーバサーバ

Server accepts and forks

リクエストaccept()

ファイルディスクリプタ

サーバ (子 )サーバ )子 (

fork()

Page 23: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

fork()を用いたマルチクライアントサーバの仕組み

クライアント 1クライアント 1

クライアント 2クライアント 2

クライアント 3クライアント 3

Client deals w/ one connection,parent is free to accept more.

ファイルディスクリプタ

サーバ (親 )サーバ )親 (

サーバ (子 )サーバ )子 (

Page 24: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

fork()を用いたマルチクライアントサーバの仕組み

クライアント 1クライアント 1

クライアント 2クライアント 2

クライアント 3クライアント 3 New client handled the same way.

ファイルディスクリプタ

サーバ (親 )サーバ )親 (

サーバ (子 )サーバ )子 (

サーバ (子 )サーバ )子 (

fork()

accept()

Page 25: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

練習 1 : forkに触れてみよう (次ページに解説あり )

#include <sys/types.h>#include <stdio.h>#include <unistd.h>int main(int argc, char *argv[]){ int pid; int number = 5; char buf[1];

printf("original process id: %d\n", getpid()); printf("original parent process id: %d\n", getppid());

if( (pid = fork()) == 0){ /* child process */ printf("this is child process\n"); number += 10; printf("number: %d\n", number); printf("fork() return value: %d\n", pid); printf("child process id: %d\n", getpid()); printf("child parent process id: %d\n", getppid()); } else if(pid > 0){ /* parent process */ printf("this is parent process\n"); number += 20; printf("number: %d\n", number); printf("fork() return value: %d\n", pid); printf("parent process id: %d\n", getpid()); printf("parent parent process id: %d\n", getppid()); } else { perror("fork()"); } printf("number: %d\n", number); exit(0);}

Page 26: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

Practice Exercise #1 included pid

int getpid() プロセス idを取得

int getppid() 親プロセス idを取得

Page 27: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

練習 1: Basic Structure ①

forkの基本構文 int pid;

if( (pid = fork()) == 0){ /* child process */} else if(pid > 0){ /* parent process */} else { perror("fork()");}

Page 28: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

練習 1 ②:重要な点 Memory with variables is copied! 変数がコピーされる

Consider int number Each process’s copy stored in separate place

original process id: 21146original parent process id: 20587

this is parent processnumber: 25fork() return value: 21147parent process id: 21146parent parent process id: 20587number: 25

this is child processnumber: 15fork() return value: 0child process id: 21147child parent process id: 21146number: 15

Page 29: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

fork()を利用した並行サーバの注意 点 (親プロセスの義務)

子プロセスが終了すると、「どのような死に様だったか」が親プロセスに伝えられる システムが親プロセスに通知 シグナルを利用

非同期な事象をプログラムで扱うための方法 親プロセスは子プロセスの死に様を見届けなければならない

親プロセスが子プロセスの終了状態を受け取らなくては,子プロセスは成仏できずにゾンビプロセスに変わる psコマンドで確認すると, a.out <defunct>と表示される

子プロセスが死んで,終了状態を受け取らずに親プロセスが死ぬと,ゾンビプロセスがいつまでも残る

子プロセスが終了する前に親プロセスが死ぬと? プロセス ID1の initが養子として引き取ってくれる

Page 30: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

終了状態の受け渡し

子プロセス 子プロセス

親プロセス

Page 31: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

終了状態の受け渡し

子プロセス 子プロセス

親プロセス

終了(正常 /異常 )

Page 32: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

終了状態の受け渡し

ゾンビプロセス 子プロセス

親プロセス

終了(正常 /異常 )

Page 33: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

終了状態の受け渡し

ゾンビプロセス 子プロセス

親プロセス

終了(正常 /異常 )

終了した子プロセスから状態を取得する

Page 34: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

終了状態の受け渡し

ゾンビプロセス 子プロセス

親プロセス

シグナルSIGCHLD

正確にはプロセスを管理している OSから通知される

Page 35: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

終了状態の受け渡し

ZombieProcess

子プロセス

親プロセス

消滅

Page 36: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

親プロセスの義務 つまり、子プロセスが終了したというシグナルを受け取ったら「南無阿弥陀仏」と唱えなければいけない 子プロセスの終了状態 (ステータス )を受け取る

呪文: wait() システムコール 子プロセスの状態を受け取り、変数へ代入 子プロセスの終了状態から、適切な処理を進められる

注意: シグナルのキューイング 複数のシグナルを同時に受信しても「1つ」しか通知されない

複数の子プロセスが同時に死んだ場合の処理を工夫

Page 37: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

Flow of Processing for Signals

何かの処理Signal Handler (parent)Child terminates

(signal created)

Finish processing

Called automatically

中断した所から実行を再開

Page 38: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

wait() System Call

Learn about status of child process pid_t wait(int *status); pid_t waitpid(pid_t wpid, int *status,

int option); 子プロセスの pidが戻り値 失敗 : -1

Page 39: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

wait()とwaitpid()の違い waitは子プロセスが終了する(ほんとは状態が変わる)までブロックする 親プロセスは別の処理を行えない。

waitpid() (see also wait4() on some OSes) ブロックしないようにするオプションがある。

WNOHANG 戻り値 0は、もう状態の変化したプロセスがない場合

pidを指定できる -1 を指定すると最初に状態の変化した子プロセス

0を指定すると、同一プロセスグループ idを持つ子プロセス

Page 40: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

Practice Exercise #2: simple wait()

Modify forktest.c to: Have child sleep() for 5 seconds Have parent wait() for child to die Include printf()s so you can see what

happens

Page 41: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

Using Signal Handlervoid sig_child(int signo) // this is the signal handler{

int pid, status;while((pid = waitpid(-1, &status, WNOHANG)) > 0) {

printf("PID: %d, terminated\n", pid);}

}

int main(int argc, char *argv[]){

…. // arranges for signal handler to be called signal(SIGCHLD, sig_child);

….}

Page 42: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

Practice Exercise #3: Using signal handler

Modify forktest.c from last exercise: Delete wait() in parent Set up signal handler (before fork())

Handler should print “Okay, I’m happy now”, then program should exit

Have parent sleep() for 1 second, wake up, print “still unhappy....”, (don’t forget to flush()!)and loop forever

Page 43: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

実習 以前つくった TCP-echo-severを forkを用いて並行処理可能にする

前回とに違い Server:

forkする “クライアントから bye”を受け取ると通信を終了する

bye以外は全て clientにエコーする waitpidする (子プロセスの終了を受け取る )

複数クライアントからサーバに接続し, psコマンドを用いて forkが出来ていることを確認すること

Page 44: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

知っておきたいシグナル SIGINT

Ctrl-Cにバインドされていて、プロセスを終了するためによく使われる

SIGTERM これもプロセスを終了するためによく使われる。 killコマンドが

defaultで送るシグナル SIGTSTP

Ctrl-Zにバインドされていて、プロセスをサスペンドするためによく使われる。

SIGCHLD fork()で作成した子プロセスが exit()したことを通知するシグナル。

これを受けて wait() などの後処理を走らせる SIGALRM

alarm()によって指定された秒数後に送られるシグナル。タイマーの実装でよく使う

Page 45: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

シグナルをする時 kill(pid_t pid, int sig)というシステムコール

pid == どちのプロセスに送る sig == シグナルナンバー

Page 46: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

シグナルハンドラの指定:signal() void (*signal(int signo, void (*func)(int)))

(int); 指定したシグナル発生時に呼び出される関数(シグナルハンドラ)へのポインタを指定する

以前に設定されていたシグナルハンドラを指すポインタが戻り値

Signoは捕捉するシグナル funcはシグナルハンドラへのポインタ

第 2引数の funcは引数として整数をひとつとり、戻り値を返さない関数へのポインタ

Page 47: ネットワークプログラミング 第 9 回「 応用ネットワークプログラミング」 #9 Applied Network Programming  (last lecture!)

( ‘ ’前回の 使い方例 )の問題点 一つのクライアントに対応している間は、他のクライアントに対応できない! 複数のクライアントが一度にアクセスした場合を考慮しなければいけない

どこがネックか? accept()を多重化して実行できると良い? 実際の処理を多重化して実行できると良い?