第5回ネットワークプ ログラミング 中村 修 今日のお題 講義 7 layer modelのおさらい TCPとUDP ネットワークプログラミング基本手順 練習1:echo clientを作ろう ---------休憩------------------------------- 実習:UDPでデータを送る/受け取る udpで echo serverを作ろう インターネットの階層モデル アプリケーション アプリケーション TCP IP データリンク 物理 IP データリンク 物理 TCP IP データリンク 物理 OSI参照モデルと インターネットの階層構造の関係 アプリケーション プレゼンテーション アプリケーション セッション トランスポート TCP UDP ネットワーク IP データリンク Network Interface 物理 物理 階層型プロトコルでのデータ送受信 送信側 各層がそれぞれ必要な情報を付加して下層へ渡す 受信側 各層がそれぞれ情報をもとに処理を行い、その使った 各層の 情報 情報を取り除いて上層へ渡す データ アプリケーション アプリケーション TCP TCP UDP UDP IP IP Network Interface Network Interface 物理 物理 送信ノード 受信ノード データ プロトコル 2つの機器間で,通信の手順を決めた約束ご と IP,TCP,HTTP,FTP コンピュータは「決まり」がないと通信できない ネットワークアプリケーションとは? process process TCP UDP IP ICMP process process ARP transport layer IGMP network layer RARP hardware interface media data link layer クライアント・サーバモデル ネットワークを介したサービスにおける通信モデル サーバ 受動的にサービス提供する側、待っててくれる クライアント 能動的にサービス提供を促す側、接続しに行く Client Server サービス要求 サービス提供 ポートとソケット ポート トランスポート層のアクセスポイント TCP/UDP毎に持っている ソケット プロセスとポートを繋ぐアダプタ ソケット(Socket) プロセス間通信を行う為のデータの出入り口 プロセスからはファイルディスクプリタを用いてアクセス プロセスにとってはプロセス間通信もファイル入出力も同じ インターフェイス プロセス socket socket プロセス socket()システムコール int socket(int family, int type, int proto) familyにはプロトコルファミリを指定 AF_INET AF_INET6 AF_LOCAL AF_ROUTE IPv4プロトコル IPv6プロトコル UNIX Domain Socket 経路制御ソケット 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 SOCK_DGRAM SOCK_RAW TCP UDP なし 初期状態 クライアント プロセス Port A サーバ プロセス Port B Port C ホストA IP Address: xx.xx.xx.xx. ホストB IP Address: xx.xx.xx.xx. Socketを開いた状態 Socketを開く クライアント プロセス Port A サーバ プロセス Port B Port C ホストA IP Address: xx.xx.xx.xx. ホストB IP Address: xx.xx.xx.xx. bindした状態 Proto LocalAdddress TCP *.A クライアント プロセス ForeignAddress *.* Port A State Closed サーバ プロセス Port B Port C ホストA IP Address: xx.xx.xx.xx. ホストB IP Address: xx.xx.xx.xx. Stream example (TCP) Server socket() bind() Client listen() socket() accept() Connection Establishmt. Block until connect recv() Process request send() Data (request) connect() send() Data (reply) recv() 暗黙にbind() Datagram example (UDP) Server socket() Client bind() socket() recvfrom() bind() Block until Data from client Data (request) sendto() Process request sendto() Data (reply) recvfrom() Datagram example2 (UDP) Server socket() Client bind() socket() recvfrom() bind() Block until Data from client connect() Data (request) send () Process request sendto() Data (reply) recv () sockaddr_in構造体 ソケットの情報 … 32bit ポート番号 … 16bit プロトコルファミリー … AF_INET… 7 15 0 アドレス 長さ protocol アドレス unused unused Port番号 31 sockaddr構造体 ソケットの情報を一般化した形 ソケットを使った通信のためのテンプレート 利用するプロトコルに依存しない 共通: 長さ・プロトコルファミリ(AF_XXX) 7 15 0 unused 長さ protocol unused unused unused 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 1 2 3 4 ビッグエンディアン 2 1 4 3 2 1 エンディアン変換 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; u_char sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; } /*IP addressのサイズ*/ /*AF_INET etc*/ /*port num*/ /*IP address*/ /*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 sockaddr *)&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の順番が逆
© Copyright 2024 ExpyDoc