Presentation is loading. Please wait.

Presentation is loading. Please wait.

CS-B3 ネットワークプログラミング 峰野博史

Similar presentations


Presentation on theme: "CS-B3 ネットワークプログラミング 峰野博史"— Presentation transcript:

1 CS-B3 ネットワークプログラミング 峰野博史 (mineno@inf.)
ネットワークプログラミング の基礎 CS-B3 ネットワークプログラミング

2 これまでの学習項目 Cプログラミング基礎 実用的な使い方 他にも様々なことができます 配列,関数,再帰関数,構造体,ポインタ,etc.
キーボード入力,画面出力 ファイル入出力 リダイレクト,コマンドライン引数 統合開発環境,etc. 他にも様々なことができます

3 その他の重要項目(一部) 実践アルゴリズム ネットワークプログラミング その他 計算量,スタック,キュー,連結リスト,木構造
ハッシュ法,二分探索木,AVL木,B木 整列,クイックソート ワイルドカードマッチング 正規表現,バックトラック,グラフ探索,etc. ネットワークプログラミング TCP/UDP,ソケットAPI,プロセス間通信,etc. その他 メモリ管理,プロセス,スレッド,システムコール,etc.

4 ネットワークプログラミング基本 ケーブルをPCに挿入する,もしくは無線LANのキーを設定するだけで世界中のホームページが見られたり,電子メールを送受信できる なぜでしょう? つながらない時は何を調べればよいのでしょう? 大切な考え方: 機能の階層的な管理!

5 機能の階層的な管理 ソフトウェア ハードウェア アプリケーション ライブラリ OS デバイスドライバ BIOS ディスプレイ キーボード
アプリケーションソフトウェア ソフトウェア アプリケーション ライブラリ OS デバイスドライバ BIOS ハードウェア ディスプレイ キーボード マウス システムコール ライブラリ関数 (サービスの要求) (サービスの要求) オペレーティグシステム(OS) (ハードウェアの制御) デバイスドライバ (OSの設定) ファームウェア (ハードウェアの制御) (ハードウェアの設定 /制御) ハードウェア

6 ライブラリ関数とシステムコール ライブラリ関数 システムコール (サービスコール,スーパーバイザコールとも言う)
ライブラリに収められた関数群 内部でシステムコールを使って実装されることもある time(), rand(), strlen(), printf(), sscanf(), etc. システムコール (サービスコール,スーパーバイザコールとも言う) OS(特にカーネル)の機能を呼び出すための機構 open, read, write, fork, socket, stat, unlink, etc.

7 トランスポートモジュール(TCP・UDP)
ネットワークモジュールの利用 ユーザモード アプリケーション アプリケーションソフトウェア システムコール プロセスの切り替え アプリケーションインターフェイス カーネルモード オペレーティングシステム (OS) トランスポートモジュール(TCP・UDP) インターネットモジュール(IP) 関数呼び出し ソフトウェア割り込み デバイスドライバ ドライバモジュール メモリまたはI/O ポートへの書き込み ハードウェア割り込み ネットワークインターフェイスカード ハードウェア

8 通信機能の「レイヤ」の考え方 Webページ www.yahoo.co.jp が見れない?
自端末にIPアドレスが設定されていない? 経路上のルータがダウン? 自端末のNIC(Network Interface Card)の故障? レイヤ毎に決められた機能間の関連(プロトコル)を理解すれば,問題の所在を突き止められる どのレイヤまで動けば何が動くはずか

9 無理やり現実社会に例えると.. 住所を書いて手紙をポストへ投函すると相手に届く IPアドレスを指定してパケットを送信すると相手に届く
住所を割り当てる 住所から配送経路を求める 郵便局を配置する 最寄りの郵便局まで歩く IPアドレスを指定してパケットを送信すると相手に届く IPアドレスを割り当てる ルーティングプロトコルで配送 ルータを設置する LANや無線LANなどで通信 現実社会 通信 名前 ホスト名 部屋番号 ポート番号 住所 IPアドレス 配送経路を決める ルーティングプロトコル 郵便局 ルータ 郵便局まで歩く LAN,無線LANなど レイヤ構造

10 通信におけるレイヤ毎の識別子 アプリケーションレベル: ホスト名,ドメイン名 トランスポートモジュールレベル: ポート番号
アプリケーションレベル: ホスト名,ドメイン名 人間が理解しやすい名前:  トランスポートモジュールレベル: ポート番号 同一通信機器内で通信を区別する識別子:  http: 80, SMTP: 25 など インターネットモジュールレベル: IPアドレス 通信機器を区別する識別子:   など デバイスドライバレベル: MACアドレス 通信機器を区別する世界で一つの識別子:  08:00:27:dd:2d:94 など ポート番号 MACアドレス ドメイン名 アプリケーション トランスポート モジュール インターネット デバイスドライバ ハードウェア ケーブル IPアドレス ホストA ホストB ルータX ルータY ホスト名

11 通信開始時の識別子変換処理① アプリケーション層: ホスト名,ドメイン名 トランスポート層: ポート番号 インターネット層: IPアドレス
アプリケーション層: ホスト名,ドメイン名 トランスポート層: ポート番号 インターネット層: IPアドレス データリンク層: MACアドレス 2.サービス名からポート番号を調べる ホストA services 1.ホスト名,ドメイン名からIPアドレスを調べる services ファイルから検索 hosts DNSデータベース ホストA DNS サーバA DNSキャッシュ DNSサーバ類 ①hostsファイルから検索 ②DNSサーバに問い合わせる ④DNSのキャッシュから検索 ③ハードディスクのデータベースから検索 ⑤他のDNSサーバへ問い合わせる

12 通信開始時の識別子変換処理② IPアドレスから,次に送るべきホストやルータを決定 > route PRINT
ネットワークA ネットワークB ホストA ホストB ルーティングテーブル ルータA ルータB 終点IPアドレスからルーティングテーブルを検索し,次にパケットを転送すべきホストやルータを決定する IPアドレスから,MACアドレスを調べる > arp -a ホストA ホストB ホストC ホストD ホストE ARPテーブル ①ARPテーブルを検索 ※ARP (Address Resolution Protocol) ②ARPテーブルにない場合にはARP要求パケットを送信 ③自分のIPアドレスに対するARP要求パケットの場合には,ARP応答パケットでMACアドレスを通知する ④通知された情報をARPテーブルに追加する(キャッシュ)

13 IPアドレス,MACアドレスの調べ方 $ ifconfig -a IPv4アドレス MACアドレス

14 通信におけるレイヤ毎の役割 アプリケーション層: FTP,telnet,HTTP,DNS,POP3,など
様々な用途に依存した処理 トランスポート層: TCP,UDP,など 宛先・送信元アプリケーションの特定,誤り制御,シーケンス制御 インターネット層: IPv4,IPv6,ARP,ICMP,など 起点から終点までのパケット配送(ルーティング)を提供する データリンク層: Ethernet,IEEE ,PPP,など 隣接する通信機器間でのフレーム配送を提供する ポート番号 MACアドレス ドメイン名 アプリケーション トランスポート モジュール インターネット デバイスドライバ ハードウェア ケーブル IPアドレス ホストA ホストB ルータX ルータY ホスト名

15 通信プロトコルとは? ネットワークを介してコンピュータ同士が通信を行なう上で,相互に決められた約束事の集合 通信手順,通信規約
プログラム = データ構造 + アルゴリズム プロトコル = パケットの構造 + 動作の定義 1年生:計算機システム演習,プログラミング(科学科) 通信の仕組みの基礎を理解 2年生:コンピュータネットワーク講義 代表的なTCP/IPプロトコル動作の詳細を理解 3年生:ネットワーク系研究室 通信プロトコル改良研究,ネットワークシステム開発研究

16 トランスポート層プロトコル TCP(Transmission Control Protocol)
IPの機能を拡張し,終点ホスト間で信頼性のある通信を提供 送信データの順序番号制御と確認応答制御を実行 コネクション指向のプロトコルで,通信開始時にコネクションを確立し,通信終了時にコネクションを切断 HTTPやSMTPなど多くのアプリケーションで利用 UDP(User Datagram Protocol) IPの機能をそのままアプリケーションから利用 コネクションレスで信頼性のないデータグラム型のサービスを提供 マルチメディアストリームを扱うアプリケーションでよく利用

17 ネットワークプログラミング ソケットシステムコール アプリケーションがOS内の通信関係のモジュールを利用するためのインタフェース
ソケットの種類 コネクション型:TCP コネクションレス型:UDP アプリケーション アプリケーション メッセージの送信 メッセージの受信 sendシステムコール recvシステムコール システムコール プロセスの 切替え オペレーティングシステム ソケットモジュール ソケット 送信キュー ソケット 受信キュー 関数呼出し 関数呼出し TCPモジュール TCP送信 キュー TCP受信 キュー 関数呼出し 関数呼出し IPモジュール IP送信 キュー IP受信 キュー ソフトウェア 割込み 関数呼出し デバイスドライバ IP送信 キュー IP受信 キュー I/Oコントロール ハードウェア 割込み ハードウェア NIC NIC送信 キュー NIC受信 キュー パケットの送信 パケットの受信

18 クライアントサーバモデル クライアント: 処理を要求するプログラム サーバ: 要求を受けて処理するプログラム
クライアント: 処理を要求するプログラム サーバ: 要求を受けて処理するプログラム (A)クライアントとサーバが別々のコンピュータで動作 ホストA ホストB 要求 クライアントプログラム サーバ プログラム 応答 (B)クライアントとサーバが同じコンピュータで動作 ホストC 要求 クライアントプログラム サーバ プログラム 応答 (C)1つのプログラムがクライアントとサーバを兼ねる ホストD ホストE ホストF 要求 要求 クライアントプログラム 1つのプログラムサーバ  クライアント サーバ プログラム 応答 応答 MTA (Mail Transfer Agent), Web Proxy Server など

19 以下重要 TCP通信の流れ クライアント側プログラム サーバ側プログラム socket() socket() ソケット作成 ソケット作成
接続相手の IPアドレスとポート番号の設定 接続待ちをする IPアドレスとポート番号の設定 bind() ソケットに名前を付ける listen() 接続を待つ connect() accept() 接続要求する 接続を受け付ける send() recv() 通信を行う 通信を行う recv() send() close() close() 終了する 終了する

20 UDP通信の流れ クライアント側プログラム サーバ側プログラム socket() socket() ソケット作成 ソケット作成 接続相手の
IPアドレスとポート番号の設定 接続待ちをする IPアドレスとポート番号の設定 bind() ソケットに名前を付ける sendto() recvfrom() 通信を行う 通信を行う recvfrom() sendto() close() close() 終了する 終了する

21 socket() ソケット作成 ファイルアクセスの open() に相当 PF_INET SOCK_STREAM クライアント側 サーバ側
返り値は,ファイルディスクリプタ PF_INET IPv4という通信体系を用いることを指定 SOCK_STREAM TCPを用いた通信を指定 int sid = socket(PF_INET, SOCK_STREAM, 0);

22 ファイルディスクリプタとは ファイルや標準入出力に振られる識別子 OSがそれぞれを識別するために使用する
クライアント側 サーバ側 ファイルディスクリプタとは ファイルや標準入出力に振られる識別子 OSがそれぞれを識別するために使用する 0は標準入力(stdin) 1が標準出力(stdout) 2が標準エラー出力(stderr) 3以降はopenされたファイルに順次割り当てる Unix/Linuxではソケットもファイルとして扱う

23 bind() 作成したソケットにポート番号などの名前を割り当てる
サーバ側 bind() 作成したソケットにポート番号などの名前を割り当てる bind()へ渡すために,まずはどのIPアドレスとポート番号で待ちうけたいかを専用の構造体へ設定する AF_INET: IPv4のアドレスであることを示す INADDR_ANY: 自身の全IPへの接続を許可することを示す htons(): ネットワークバイトオーダへ変換 送受信するバイトの順番で,TCP/IPは最上位バイトから順番に記録/送信するビッグエンディアンとなる クライアント側UDP送信元ポート番号などの指定が不要な場合は bind() しなくてもよい struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(50001); int ret = bind(sid, (struct sockaddr *)&addr, sizeof(addr));

24 bind()でよく発生するエラー 「Address already in use」 要求したポート番号が既に使われていますよ
サーバ側 bind()でよく発生するエラー 「Address already in use」 要求したポート番号が既に使われていますよ 基本的には,ソケットをきちんと close() すればOK close() すればそのポート番号は再利用可能 ただし,close() してから実際に再利用可能になるまで少し時間がかかる そのポートに対してどこかからパケットが飛んでくる可能性があるから ※bind()に限らず全てのシステムコールで,成功したかどうかエラー処理を記述しておくべき

25 listen() TCPコネクション要求を受け付け開始しますよという宣言
サーバ側 listen() TCPコネクション要求を受け付け開始しますよという宣言 クライアントからのTCPコネクション接続要求(connect()システムコール)を受け付ける 接続相手とTCPコネクションを張るのは後述の accept() 第二引数の数字は,複数の接続要求が同時に殺到し accept() が間に合わない時,いくつまでTCPコネクションを保持できるかの最大数 int ret = listen(sid, 10);

26 connect() 指定したIPアドレスとポート番号へ接続要求 クライアント側 struct sockaddr_in addr;
AF_INET: IPv4のアドレスであることを示す inet_addr(): IPアドレス文字列を32bit形式に変換 htons(): ネットワークバイトオーダへ変換 送受信するバイトの順番で,TCP/IPは最上位バイトから順番に記録/送信するビッグエンディアンとなる struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(“ ”); addr.sin_port = htons(50001); int ret = connect(sid, (struct sockaddr *)&addr, sizeof(addr));

27 accept() 待ちうけポートでTCPコネクション接続要求を受け,クライアントと通信するための新たなソケットを生成 サーバ側
以下のクライアントの情報を client_addr へ受け取る accept() に成功したら,以降クライアントとの送受信は,この新たなソケットを用いて実施される struct sockaddr_in client_addr; socklen_t len = sizeof(client_addr); int ss = accept(sid, (struct sockaddr *)&client_addr, &len);

28 send()/sendto()/recv()/recvfrom()
クライアント側 サーバ側 send()/sendto()/recv()/recvfrom() TCPコネクション確立後にデータの送受信が可能 ファイルアクセスの read() や write() に相当 UDPでデータの送受信が可能 n = send(sid, data, N, 0); もしくは n = recv(sid, data, N, 0); n = sendto(sid, data, N, 0, &dest_addr, sizeof(dest_addr)); もしくは n = recvfrom(sid, data, N, 0, &from_addr, &from_len);

29 close()/shutdown() ソケットを閉じる 自身の送信は終了するが,やってくるデータは受け取りたい場合
クライアント側 サーバ側 close()/shutdown() ソケットを閉じる 作成したソケットを終了し,これ以降,このソケットを用いることはできない 自身の送信は終了するが,やってくるデータは受け取りたい場合 現段階ではあまり気にしなくて良い close(sid); shutdown(sid, SHUT_WR);

30 gethostbyname() ホスト名からIPアドレスへの変換を行ってくれる関数 #include <netdb.h>
struct hostent *addr; /* アドレス情報を格納するhostent構造体 */ /* IPアドレス取得 */ if ((addr= gethostbyname(argv[1]) == NULL){   /* 失敗すると NULL */ printf(“gethostbyname() failed!\n"); } printf(“gethostbyname() Success!!\n");

31 まとめ:主要なソケットシステムコール socket() ソケットを開く close() ソケットを閉じる
※引数型の詳細は処理系に依存しますので man コマンドで確認しましょう まとめ:主要なソケットシステムコール socket() ソケットを開く close() ソケットを閉じる bind() 自ホストのIPアドレス,ポート番号の設定 listen() TCPコネクションの受け付け開始 connect() TCPコネクション確立要求 相手ホストのIPアドレス,ポート番号を指定 accept() 受け付けたTCPコネクション用にソケットを作成 send() メッセージの送信(TCP) sendto() メッセージの送信(UDP) recv() メッセージの受信(TCP) recvfrom() メッセージの受信(UDP) select() 入出力の多重化 setsockopt() ソケットオプションの設定

32 まとめ:主要なソケットライブラリ関数 gethostbyname() ドメイン名からIPアドレスを取得
※引数型の詳細は処理系に依存しますので man コマンドで確認しましょう まとめ:主要なソケットライブラリ関数 gethostbyname() ドメイン名からIPアドレスを取得 gethostbyaddr() IPアドレスからドメイン名を取得 getservbyname() キーワードからポート番号を取得 getservbyport() ポート番号からキーワードを取得 inet_addr() 文字列のIPアドレスを構造体に変換 inet_ntoa() IPアドレス構造体を文字列に変換 htonl() ネットワークバイトオーダに変換(long) htons() ネットワークバイトオーダに変換(short) ntohl() ホストバイトオーダに変換(long) ntohs() ホストバイトオーダに変換(short) getaddrinfo() ドメイン名からIPアドレスを取得, キーワードからポート番号を取得 getnameinfo() IPアドレスからドメイン名を取得, ポート番号からキーワードを取得

33 まとめ:主要なソケット構造体 sockaddr_in構造体: IPアドレスやポート番号などを格納 in_addr構造体: IPアドレスを格納
通常,自分と相手用の情報を格納する2つの変数を用意 in_addr構造体:   IPアドレスを格納 hostent構造体:   通常,gethostbyname()によってホスト情報を格納 struct sockaddr_in { u_char sin_family; /* address family(通常はAF_INET) */ u_short sin_port; /* ポート番号(htonsでネットワークバイトオーダに) */ struct in_addr sin_addr; /* IPアドレスを格納したin_addr構造体 */ char sin_zero[8]; /* 通常は0で初期化しておく */ }; struct in_addr { u_int32_t s_addr; /* IPアドレスをネットワークバイトオーダで*/ }; struct hostent { char *h_name; /* ホストの正式名称(FDQN) */ char **h_aliases; /* ホストの別名 */ int h_addrtype: /* アドレスタイプ(通常はAF_INET) */ int h_length; /* アドレスのサイズ(IPv4の場合4,IPv6の場合16) */ char **h_addr_list;   /* アドレスのリスト(通常,define h_addr h_addr_list[0] ) */ };


Download ppt "CS-B3 ネットワークプログラミング 峰野博史"

Similar presentations


Ads by Google