ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2)...

33
ネネネネネネネネネネネネネ ネ 7 ネ ネネネネネネネネネネネネネネ (2) 20 10 ネネネネ Rodney Van Meter

Upload: licia

Post on 27-Jan-2016

59 views

Category:

Documents


0 download

DESCRIPTION

20 10 年秋学期 Rodney Van Meter. ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」. 今期の授業スケジュール(予定). 第1回 9/28 : Introduction / イントロダクション 第2回 10/5 : C Basics ~ Functions, Variables, Data Types ・ Makefiles 第3回 10/12 : C Basics ~ Command Line Arguments ・ Structures ・ Pointers - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

ネットワークプログラミング第 7回「ネットワークとプログラミング (2)」

20 10年秋学期Rodney Van Meter

Page 2: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

今期の授業スケジュール(予定) 第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) 第9回 11/30 : Applied Network Programming ( 1) 第10回 12/7 : Applied Network Programming (2) 第11回 12/14 : Work on Projects 第1 2 回 12/21 : Work on Projects 第13回 1/11 : Final Presentations!!!

Page 3: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

今日のお題 Last week’s work: TCP-success-server Lecture

TCP programming TCP-echo-client

getaddrinfo(), gethostbyname() connect()

Practice/HW: report-attendance!

Page 4: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

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()

Page 5: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <stdio.h>

#define BUFMAX 1024

int main(int argc, char *argv[]){int sd; int cc, svadlen;char buf[BUFMAX]char rmsg[BUFMAX];struct sockaddr_in cl_addr, sv_addr;

/* make socket */????

/* give a name to the socket */????

/* set the socket address */????

/* processing */????

return 0;

}

Page 6: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

課題:できた?

Page 7: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

TCPプログラミング

Page 8: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

TCP (Transmission Control Protocol)

信頼性のある通信を提供 データレート制御:不可・困難

身近な例 電子メール WEB

イメージ電話のやりとり

S:もしもし C: ○○もしもし、 です S:××です。あのさ、、、

serverclient

SYN

SYN+ACK

ACK

データ

Page 9: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

TCP Comm Flow (server)

socket()

bind()

listen()

accept()

socket()

connect()

read()

close()

TCP client

TCP Server

write()read()

write()

read()

close()

data

data

establish

end

fork();

exit();

Page 10: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

Socketを開いた状態

クライアントプロセス

ホスト A

サーバプロセス

ホスト B

Port B

IP Address: xx.xx.xx.xx.

Port C

Port A

Socketを開く

IP Address: yy.yy.yy.yy

Page 11: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

bind()システムコール int bind(int s, const struct sockaddr *addr, int addrlen) 用意した socketのアドレスを実際に socketと結びつける

IPアドレスと TCP/UDPのポート番号の組 開いたソケットのステートは closed

…実際のコードでは bind(listenfd, (struct sockaddr *) &servaddr,

sizeof(servaddr) 成功なら 0、エラーなら -1の返り値

Page 12: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

Bound to an address

クライアントプロセス

ホスト A

サーバプロセス

ホスト B

Port B

IP Address: xx.xx.xx.xx.

Port C

Port A

Proto LocalAddress ForeignAddress StateTCP *.A *.* Closed

IP Address: yy.yy.yy.yy

Page 13: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

bind

int bind(int sockfd,struct sockaddr *addr,int addrlen);(例 )

struct sockaddr_in cl_addr;

memset((void *)&cl_addr, 0, sizeof(cl_addr));cl_addr.sin_family = AF_INET;cl_addr.sin_port = htons(0);cl_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* local host*/

bind(sd,(struct sockaddr *)&cl_addr, sizeof(cl_addr))

Page 14: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

Listen()

クライアントプロセス

ホスト A

サーバプロセス

ホスト B

Port B

IP Address: xx.xx.xx.xx.

Port C

Port A

Proto LocalAddress ForeignAddress StateTCP *.A *.* Listen

IP Address: yy.yy.yy.yy

Page 15: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

accept() System Call int accept(int s, struct sockaddr *addr, int

*addrlen) キューで待っている接続要求を取り出して、そのクライアントと通信するためのディスクリプタを作成して、返す

clientにはクライアントの socketのアドレス、 namelenには clientのサイズ

…実際のコードでは accept(listenfd, (struct sockaddr *) &cliaddr,

&clilen) 成功なら新しい FD番号、エラーなら -1の返り値

Page 16: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

accept()

クライアントプロセス

ホスト A

サーバプロセス

ホスト B

Port B

IP Address: xx.xx.xx.xx.IP Address: yy.yy.yy.yy

Port C

Port APort X

Connect()

Proto LocalAdddress ForeignAddress StateTCP xx.xx.xx.xx.A yy.yy.yy.yy.X Establish

Page 17: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

accept()

クライアントプロセス

ホスト A

サーバプロセス

ホスト B

Port B

IP Address: xx.xx.xx.xx.IP Address: yy.yy.yy.yy

Port C

Port APort X

Connect()

Proto LocalAdddress ForeignAddress StateTCP *.A *.* ListenTCP xx.xx.xx.xx.A yy.yy.yy.yy.X Establish

Page 18: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

Usage

int socket_fd, accept_fd;int client_addrlen;int readlen;struct sockaddr_in server, client; socket_fd = socket(AF_INET,SOCK_STREAM, 0);memset((void *)&server, 0, sizeof(server)); bind(socket_fd, (struct sockaddr *)&server, sizeof(struct sockaddr_in));listen(socket_fd, 5);memset((void *)&client, 0, sizeof(client));client_addrlen = sizeof(client)accept_fd = accept(socket_fd,(struct sockaddr *)&client, (int *)&client_addrlen); ---( read/writeなどの処理) ----close(accept_fd);close(socket_fd);}

Page 19: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

TCP code flow (client)

socket()

bind()

listen()

accept()

socket()

connect()

read()

close()

TCP client

TCP Server

write()read()

write()

read()

close()

data

data

establish

end

Page 20: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

connect() System Call Connects this socket to the far end #include <sys/types.h> #include <sys/socket.h> int connect(int sockfd, const struct

sockaddr *serv_addr, socklen_t addrlen); int sockfd; (ソケット記述子 ) struct sockaddr *serv_addr; (プロトコル対応のアドレス構造体へのポインタ )

socklen_t addrlen; (アドレス構造体のサイズ ) Return value:

0 on success, -1 on failure

client server

Page 21: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

New-style naming: getaddrinfo() if (error = getaddrinfo(host, service, &hints, &ai)) {

fprintf(stderr, "getaddrinfo(%s, %s, ...): %s (%d)\n", host, service, gai_strerror(error),

error);

exit(-1);

}

/* loop through addrinfos until we get a good connect */

for (ai2 = ai; ai; ai = ai->ai_next) {

socket();

connect(fd, ai->ai_addr, ai->ai_addrlen);

/* break; once you get one that works */

}

Page 22: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

New-style naming: getnameinfo() if (error = getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf,

sizeof(hbuf), sbuf, sizeof(sbuf),

NI_NUMERICHOST | NI_NUMERICSERV)) {

fprintf(stderr, "getnameinfo(%p, %d, %p, %d, %p, %d, %d): %s(%d)\n",

ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),

NI_NUMERICHOST | NI_NUMERICSERV, gai_strerror(error), error);

continue;

}

fprintf(stdout, "Trying %s port %s...\n", hbuf, sbuf);

Page 23: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

Using sendto()

ssize_t sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, int tolen);

(例)if (sendto(sd, (char *)&msg, sizeof(msg), 0 ,

(struct sockaddr *)&sv_addr, sizeof(sv_addr)) < 0) { perror("sendto"); exit(-1);

}

Page 24: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

read() and write()

For a TCP socket, can just use read() and write() once you’re connected

Be careful about message ordering!Who is waiting on whom?

Also can use send(), recv()

Page 25: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

Using 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 *)&sv_addr, &svadlen);

Page 26: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

Homework (1): TCP Client for Simple Attendance Server

Two arguments: IP address (v4 or v6) Port number

Sends student ID number

次ページにポイント説明あり

Page 27: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

Homework (2): Proposal for Term Project

First round: Basic idea (2-3 paragraphs) 2-4 Team members (name, login

name/nickname, student ID number)

次ページにポイント説明あり

Page 28: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

Next Week: More Complete Proposal for Term Project

“Value Proposition” (why do I care?) Related work (has it been done

before?) Key Idea How you will evaluate Schedule with technical milestones

次ページにポイント説明あり

Page 29: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

Old style: gethostbyname() Resolves host name to IP address #include <unistd.h> struct hostent gethostname(const char

*name); 例

struct sockaddr_in sin;struct hostent *shost;shost = gethostbyname(argv[1]); sin.sin_addr = *(struct in_addr *)hp->h_addr;

Page 30: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

sample#include <netdb.h> int main (int argc, char *argv[] ) {

int sock_fd; struct sockaddr_in sin; char buf[BUF_SIZE]; int readlen; struct hostent *hp;

hp = gethostbyname( argv[1] ); /* add */

sock_fd = socket(AF_INET, SOCK_STREAM, 0);

sin.sin_family = AF_INET; sin.sin_port = htons(SERV_PORT); sin.sin_addr = *(struct in_addr *)hp->h_addr;

}

Page 31: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

hostent structurestruct hostent{

char *h_name; /* official name of host */

char **h_aliases; /* alias list */int h_addrtype /* host address type */

int h_length /* length of address */char **h_addr_list; /* list of addresses

*/

}#define h_addr h_addr_list[0] /* for backward

compatibility

Page 32: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

練習 : ポイント sock_fd = socket(AF_INET, SOCK_STREAM, 0);

sin.sin_family = AF_INET; sin.sin_port = htons(SERV_PORT); sin.sin_addr = *(struct in_addr *)hp->h_addr;

connect(sock_fd, (struct sockaddr *)&sin, sizeof(sin));

fgets(buf,sizeof(buf),stdin);

write(sock_fd, buf, readlen);

readlen = read(sock_fd, buf, sizeof(buf));

printf("%s\n",buf);

Page 33: ネットワークプログラミング 第 7 回「ネットワークとプログラミング (2) 」

gethostname() Gets name of your host #include <unistd.h> int gethostname(char *name, size_t len); Return value: 0 on success, -1 on failure 例:

char shostname[64];

gethostname(shostname, sizeof(shostname));