第 5 回ネットワークプログラミング
Post on 20-Jan-2016
62 Views
Preview:
DESCRIPTION
TRANSCRIPT
第 5 回ネットワークプログラミング
中村 修
今日のお題 講義
7 layer model のおさらいTCP と UDPネットワークプログラミング基本手順
練習1 :echo client を作ろう
--------- 休憩 -------------------------------- 実習: UDP でデータを送る / 受け取る
udp で echo server を作ろう
インターネットの階層モデル
物理データリンク
IP
物理データリンク
IP
TCP
アプリケーション
物理データリンク
IP
TCP
アプリケーション
OSI 参照モデルとインターネットの階層構造の関係
セッショントランスポート
アプリケーションプレゼンテーション
ネットワークデータリンク物理
UDPTCP
アプリケーション
IP
Network Interface
物理
階層型プロトコルでのデータ送受信 送信側
各層がそれぞれ必要な情報を付加して下層へ渡す 受信側
各層がそれぞれ情報をもとに処理を行い、その使った情報を取り除いて上層へ渡す
UDP
Network Interface
TCP
アプリケーション
物理
IP
UDP
Network Interface
TCP
アプリケーション
物理
IP
送信ノード 受信ノード
データ データ各層の
情報
プロトコル 2つの機器間で,通信の手順を決めた約
束ごと IP , TCP , HTTP , FTP
コンピュータは「決まり」がないと通信できない
ネットワークアプリケーションとは?
ARP
hardwareinterface
RARP
media
IPICMP IGMP
TCP UDP
networklayer
data linklayer
transportlayer
process process process process
クライアント・サーバモデル ネットワークを介したサービスにおける通信モデル
サーバ 受動的にサービス提供する側、待っててくれる
クライアント 能動的にサービス提供を促す側、接続しに行く
Client Serverサービス要求
サービス提供
ポートとソケット ポート
トランスポート層のアクセスポイントTCP/UDP 毎に持っている
ソケットプロセスとポートを繋ぐアダプタ
socketsocket
ソケット (Socket)
プロセス間通信を行う為のデータの出入り口 プロセスからはファイルディスクプリタを用いてアクセス プロセスにとってはプロセス間通信もファイル入出力も同
じインターフェイス
プロセス プロセス
socket() システムコール int socket(int family, int type, int proto)
family にはプロトコルファミリを指定 AF_INET IPv4 プロトコル AF_INET6 IPv6 プロトコル AF_LOCAL UNIX Domain Socket AF_ROUTE 経路制御ソケット
Type にはソケットのタイプ(以下のどれか)
SOCK_STREAM ストリームソケット SOCK_DGRAM データグラムソケット SOCK_RAW raw ソケット
Proto には raw ソケット以外、通常0
socket() システムコール 返り値
成功 : ソケットディスクリプタが返る 失敗 : -1 が返る
ソケットディスクリプタはファイルディスクリプタの友達 実際のコードでは…
listenfd = socket(AF_INET, SOCK_STREAM, 0)
AF_INET の場合の利用される IPv4 の上位層 SOCK_STREAM TCP SOCK_DGRAM UDP SOCK_RAW なし
初期状態
クライアントプロセス
ホスト A
サーバプロセス
ホスト B
Port B
IP Address: xx.xx.xx.xx.IP Address: xx.xx.xx.xx.
Port C
Port A
Socket を開いた状態
クライアントプロセス
ホスト A
サーバプロセス
ホスト B
Port B
IP Address: xx.xx.xx.xx.IP Address: xx.xx.xx.xx.
Port C
Port A
Socketを開く
bind した状態
クライアントプロセス
ホスト A
サーバプロセス
ホスト B
Port B
IP Address: xx.xx.xx.xx.IP Address: xx.xx.xx.xx.
Port C
Port A
Proto LocalAdddress ForeignAddress StateTCP *.A *.* Closed
Stream example (TCP)Server
socket()
bind()
Client
socket()listen()
accept()
recv()
send()
connect()
send()
recv()
Block untilconnect
Processrequest
Connection Establishmt.
Data (request)
Data (reply)
暗黙に bind()
Datagram example (UDP)Server
socket()
bind()Client
socket()
recvfrom()
sendto()
bind()
sendto()
recvfrom()
Block untilData from client
Processrequest
Data (request)
Data (reply)
Datagram example2 (UDP)Server
socket()
bind()Client
socket()
recvfrom()
sendto()
bind()
send ()
recv ()
Block untilData from client
Processrequest
Data (request)
Data (reply)
connect()
sockaddr_in 構造体 ソケットの情報
アドレス … 32bit ポート番号 … 16bit プロトコルファミリー … AF_INET…
長さ protocol Port番号
アドレス
unused
unused
0 7 15 31
sockaddr 構造体 ソケットの情報を一般化した形
ソケットを使った通信のためのテンプレート 利用するプロトコルに依存しない 共通: 長さ・プロトコルファミリ (AF_XXX)
長さ protocol unused
unused
unused
unused
0 7 15 31
キャスト ある変数・構造体を無理やり違う型の変数や構造体とし
て扱う方法 変数を使う時に扱いたい型をカッコで括る
(int)no_int_variable; ← int 型にキャスト 関数の引数を一般化するのに便利
sockaddr の例 struct sockaddr_in sin; (struct sockaddr)sin;
型やサイズに依存せず 1 バイトずつ読みたいときにも使うlong addr = 1234567; char *cp = (char *)&addr;for(j = 0; j < 4; j++) {
printf("%c ", *cp++);}
inet_addr()
in_addr_t inet_addr(const char *strptr); アドレスを表す文字列を,
ネットワークバイト順序のバイナリ値へ 「 127.0.0.1 」という文字列は人間には
分かりやすいが,コンピュータには分かりにくい
仲間 inet_aton() inet_ntoa()
ネットワーク・バイト・オーダ Network Byte Order CPU アーキテクチャによって、バイトの並びが違う
一般に Big Endian(sparc 等 ) と Little Endian(Intel 等 ) の二つ ネットワーク上に流すバイト順を統一しなくてはならない
Big Endian に統一 htons()/htonl()/ntohs()/ntohl() を利用
リトルエンディアン ビッグエンディアン
16ビット整数( short)
32ビット整数( long)
1 2 12
1 2 3 4 1234
エンディアン変換 u_long htonl(u_long hostlong); u_short htons(u_short hostshort); u_long ntohl(u_long netlong); u_short ntohs(u_short netshort);
練習 1:echo クライアント作成 echo サーバは以下
hi.sfc.wide.ad.jp
port 7 番
必要な構造体 #include<netinet/in.h>
struct sockaddr_in{
u_char sin_len; /*IP address のサイズ*/
u_char sin_family; /*AF_INET etc*/
u_short sin_port; /*port num*/
struct in_addr sin_addr; /*IP address*/
char sin_zero[8]; /*padding*/
}
必要な関数 socket bind sendto recvfrom
socket
int socket(int domain, int type, int protocol);
( 例 )sd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)
AF_UNIX , SOCK_STREAM,IPPROTO_TCP
SOCK_RAW,IPPROTO_ICMP
bind
int bind(int sockfd,struct sockaddr *addr,int addrlen);( 例 )
struct sockaddr_in server;
memset((void *)&server, 0, sizeof(server));server.sin_family = AF_INET;server.sin_port = htons(7);server.sin_addr.s_addr = INADDR_ANY; /* local host*/
bind(sd,(struct sockaddr *)&server, sizeof(server))
sendto
ssize_t sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, int tolen);
(例)if (sendto(s, (char *)&msg, sizeof(msg), 0 , (struct s
ockaddr *)&server, sizeof(server)) < 0) { perror("sendto"); exit(-1);
}
recvfrom
ssize_t recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, int *fromlen);
( 例 )
recvlen = recvfrom(sd, (void *)buf, 1024, 0, (struct sockaddr *)&client, &clientlen);
実習
echo サーバを作ろう。基本的に echo クライアントと同じ
sendto,recvfrom の順番が逆
top related