ネットワークプログラミング 第4回 システムコール 低水準入力 ファイルディスクリプタ ソケット ライブラリとシステムコール • ライブラリ – 便利な関数 – オペレーティングシステムに必ずしも要求を行わない – ライブラリを利用すると、ユーザが直接オペレーション システムに要求しなくても勝手にやってくれる。 • システムコール – オペレーティングシステムにユーザが直接要求を行う – システムコールの数はあまり多くない システムコール • どんなことができる? – – – – 入出力やファイルシステムへの低水準な操作 プロセスに対するさまざまな制御 ネットワークへの対応 ライブラリでは手のとどかない部分を操作できる。 • 返り値 – システムコールは、エラーが生じると-1を返す – エラーがない場合は整数値か0を返す – 予約された外部参照変数 errnoには、どのエラーが発生 したかを示す番号がセットされる(error.h) 低水準入力 • ライブラリを通さず、直接ユーザがファイル やデバイスの操作を行う – 読み込み、書き込み、etc … • UNIXではファイル、デバイス、ネットワーク、 プロセスなどあらゆるものがファイルとして 抽象化されている – 低水準入力で、ファイルとして抽象化されたあ らゆる対象を操作できる ファイルディスクリプタ • プロセスが外の世界と通信する為のデータの出入り口 • ファイルやデバイスの操作、他プロセスとの通信など、外 の世界とのIO全てがファイルディスクリプタを経由 • プロセスから見ると整数値 ファイル ファイル デバイス 0 プロセス 1 2 0:標準入力 1:標準出力 2:標準エラー出力 ファイルディスクリプタの操作 • Open() – Openシステムコールを使い、ユーザはファイルやデバ イスをプロセスから利用可能にする。Openは戻り値に 整数値(ファイルディスクリプタを返す) – Ex. fd = open(“naisho.txt”, O_RDONLY) /* naisho.txt を読み出し専用で開く */ • Close() – ファイルディスクリプタのクローズ – Ex. close(fd) /*fdは過去にopen したファイルディスクリプタ*/ 読み書き • read(int fd, void *buf, size_t nbytes) – fd からbuf へ nbytes だけ読み込む – Buf は事前にmallocしておく – 返り値は、実際に読み出したバイト数 • write(int fd, void *buf, size_t nbytes) – fd へbuf から nbyteだけ書き込む – 返り値は、実際に書き込んだバイト数 ソケット(Socket) • • • プロセス間通信を行う為のデータの出入り口 プロセスからはファイルディスクプリタを用いてアクセス プロセスにとってはプロセス間通信もファイル入出力も 同じインターフェイス プロセス socket socket プロセス ネットワークの話 階層化構造 MACアドレス、IPアドレス ポート TCP/UDP メッセージを伝えるには • 思ったことを伝えるには – 言葉や、身振り手振りで伝える – 何かを媒介して相手に伝える • なぜ、伝わるか – 言葉 • 発した言葉、書かれた記事の意味と同じ意味を相手も知っ ている – 身振り手振り • 相手の動作がどんな意味を持つか、コンテクストやコード から推測 役割分担: 階層モデル 発話者 受話者 意思の伝達 意思の言葉への変換 言語の伝達 空気 物理的な伝達 コンピュータネットワークにおける 階層化モデル • OSI参照7層モデル – コンピュータネットワークモデルの基礎 • コンピュータ同士がコミュニケーションする場合も 階層がある。 – 人間の脳⇔脳、口⇔耳と同じ • 各層は上下の層とだけ関係を持つ – 脳は口や耳と関係を持つが空気とは直接関係しない – 自分の一つ上と一つ下以外とは話をしない OSI参照7層モデル • コンピュータネットワークのアーキテクチャを論理的に整理 • プロトコル設計の物差し Application Application Presentation Presentation Session Session Transport Transport Network Network Datalink Datalink Physical Physical OSI参照モデルと インターネットの階層構造の関係 OSI参照7層モデル インターネットの階層構造 Application Presentation Application Session Transport TCP UDP Network IP Datalink NIC, データリンクプロトコル Physical Physical インターネットの階層モデル • IPによってエンドエンドの通信が確立 • TCP/UDPによって通信の性質を選択 – TCPによって信頼性のある通信を行う – UDPによって信頼性がないが、高速で単純な通信を行う Application Application Application Application TCP TCP TCP TCP IP IP IP IP Datalink Datalink Datalink Datalink Physical Physical Physical Physical 各層での識別子 • 各層ごとに識別子が存在する • 各層は層毎に相手を識別している Application TCP UDP IP Network Interface Physical ポート番号 IPアドレス MACアドレス MACアドレス • 通信機器が持つ識別子 – – – – 通信機器ごとにユニークなアドレスを持つ 固定で割り当てられる IEEEが管理、割り当て 00:90:99:1F:95:E3 • NIC(Network Interface Card)が持っている IPアドレス • インターネット上のコンピュータの識別子 – – – – コミュニケーション相手の場所を指定できる 電話番号や住所に相当 IPv4では32bit、IPv6では128bit アドレス表記 • IPv4 • IPv6 203.178.143.1 とか 2001:200:0:1000::1 とか – 識別できるアドレスの数 • IPv4 … 32bit …. 約43億個 • IPv6 … 128bit …. 2^128個 ポート番号 • サービスの識別子(0~65535) • プロトコルごとに独立したポートを持つ – Ex. TCPの53番とUDPの53番は別のサービス • コミュニケーションの相手を指定できる – 住所(IP address)に対する部屋番号に相当 コーポシュガーの“202号室” – 電話 … 相手の呼び出し 「“りんご君”をお願いします。」 • IPアドレスとポート番号の組で、コミュニケーショ ンしたい相手を特定できる • 誰かが使っているポートは、他のプロセスは使 えない。 Wellknownポート • 1~1023番 – – – – – あらかじめ予約されているポート Ssh 22番 telnet 23番 dns 53番 http 80番 • /etc/services telnet で遊ぶ • telnet 相手先IPアドレス ポート番号 – 相手先の指定したポート番号を使っているア プリケーション(server)にTCPでコネクションが 張れる。 – SMTPサーバと話してみよう – WEBサーバと話してみよう トランスポートプロトコル • UDP(User Datagram Protocol) – 信頼性のないデータグラム型通信 – Connectionless • TCP(Transmission Control Protocol) – 信頼性のあるストリーム型通信 – Connection Oriented – Virtual Circuit UDP (User Datagram Protocol) • 送信者は、パケットを順に送り出すだけ • 受信側は、受け取ったパケットを受け取っ た順に上位層に渡すだけ – 誤りが見つかっても、途中でパケットが消失し ても再送信は行わない – パケットの順序も気にしない UDPを用いたサービス • パケット損失率や伝播遅延の変動が少ない 安定した通信路を想定 – NFS, TFTP, SNMP • 即時性、実時間性重視 – DNS, 音声/動画ストリーミングアプリケーション TCP (Transmission Control Protocol) • アプリケーション間に信頼性のある通信を提供 • IPが提供する通信に信頼性を与える – – – – – コネクション型通信 再送機能 エラー検出とエラー訂正 フロー制御 順序の再構成 TCPを用いたサービス • データの信頼性を保証したい – HTTP、FTP、SMTP – コンピュータ同士が遠く離れていても大丈夫 • データが届く順番を確保したい – SSH、チャット クライアント・サーバモデル • サーバは特定のアドレスとポートで、クライアント が接続するのを待っている • クライアントが使うポートは、起動時に割り当てら れる。 WWW Server IP address: 133.27.4.212 Port: 80, TCP Client 133.27.4.212 TCPの80番にアクセス 階層化構造に直してみると。。 www client www server TCP telnet server #80 #53 #2048 UDP dns server transport layer UDP #23 TCP IP network layer IP Ethernet Datalink/ Physical layer Ethernet プログラミング Socket Bind Socketのread/write イメージを明確にすると… ソケット クライアント プロセス Port X ソケット Port A サーバ プロセス Port B Port C ホストA IP Address: yy.yy.yy.yy ホストB IP Address: xx.xx.xx.xx. socket()システムコール • int socket(int family, int type, int proto) – プロセスから利用できるsocketを獲得 – familyにはプロトコルファミリを指定 • AF_INET • AF_INET6 IPv4プロトコル IPv6プロトコル – Typeにはソケットのタイプ(以下のどれか) • SOCK_STREAM • SOCK_DGRAM • SOCK_RAW ストリームソケット データグラムソケット rawソケット – Protoにはrawソケット以外、通常0 socket()システムコール • 返り値 – 成功: ソケットディスクリプタが返る – 失敗: -1が返る • ソケットディスクリプタはファイルディスクリプタの友達 • 例 int fd; fd = socket(AF_INET, SOCK_STREAM, 0); • 通信に利用するには、各ソケットに宛先IPアドレスや ポート番号を結びつける必要がある sockaddr_in構造体 • ソケットの情報を格納 struct sockaddr_in { u_char sin_len; u_char sin_family; /* AF_INET,AF_INET6…*/ u_short sin_port; /*相手先ポート番号 16bit */ struct in_addr sin_addr; /*相手先アドレス */ char sin_zero[8]; }; Connect()システムコール • Int connect(int s, const struct sockaddr *name, socklen_t namelen); • 第二引数で指すSockaddr構造体が通信先を特定 • 実際のコードの例 Struct sockaddr_in sin; Sin.sin_family = AF_INET /*プロトコルファミリー */ sin.sin_addr.s_addr = inet_addr(“203.178.143.1”); /* IPアドレス*/ Sin.sin_port = htons(1234); /* ポート番号 */ Connect(s, (struct sockaddr *)&sin, sizeof(sin)); • 成功なら0, エラーなら-1の返り値 ネットワーク・バイト・オーダ • Network Byte Order • CPUアーキテクチャによって、バイトの並びが違う – 一般にBig Endian(sparc等)とLittle Endian(Intel等)の二つ • ネットワーク上に流すバイト順を統一しなくてはならない – Big Endianに統一 リトルエンディアン 16ビット整数 (short) 32ビット整数 (long) 1 2 1 2 3 4 ビッグエンディアン 2 1 4 3 2 1 ネットワーク・バイト・オーダ • ntohs()/ntohl() – Short, longをホストのバイトオーダに変換 • htons()/htonl() – Short, longをネットワークバイトオーダに変換 • Inet_addr() – “203.178.143.1”のような文字列をネットワーク バイト・オーダーのlongに変換 今日の実習 • catプログラムを作る – Open, read, writeの習得 • Echoクライアントを作る – Socket, connect – Sockaddr_in構造体 – ソケットへのread, write
© Copyright 2024 ExpyDoc