Presentation is loading. Please wait.

Presentation is loading. Please wait.

Network Programming:

Similar presentations


Presentation on theme: "Network Programming:"— Presentation transcript:

1 Network Programming: http://network.hanbat.ac.kr

2 소켓 (socket) 이란 ?  The interface that the OS provides to its networking subsystem application layer transport layer (TCP/UDP) network layer (IP) link layer (e.g. ethernet) application layer transport layer (TCP/UDP) network layer (IP) link layer (e.g. ethernet) User Process Socket Internet http://network.hanbat.ac.kr2 Application Socket API TCPUDP...

3 Two Types of Application Processes Communication  Datagram Socket (UDP)  Collection of messages  Connectionless  sendto, recvfrom  No error/flow control  Best effort  Stream Socket (TCP)  Stream of bytes  Connection-oriented  connect…  send, recv  disconnect  Error/flow control  Reliable http://network.hanbat.ac.kr3

4 Clients and Servers http://network.hanbat.ac.kr4 Client program – Running on end host – Requests service – E.g., Web browser Server program – Running on end host – Provides service – E.g., Web server GET /index.html “Site under construction”

5 http://network.hanbat.ac.kr5 Client “sometimes on” – Initiates a request to the server when interested Web browser on your laptop or cell phone – Doesn’t communicate directly with other clients – Needs to know server’s address Server is “always on” – Handles services requests from many client hosts Web server for the www.cnn.com – Doesn’t initiate contact with the clients – Needs fixed, known address GET /index.html “Site under construction”

6 Socket Addresses  Popular applications have well-known ports  E.g., port 80 for Web and port 25 for e-mail  /etc/services  Port # in TCP/UDP packet header  Destination port #, source port #  Well-known vs. ephemeral ports  Server has a well-known port (e.g., port 80 for http)  Between 0 and 1023 (requires root to use)  Client picks an unused ephemeral (i.e., temporary) port  Between 1024 and 65535 http://network.hanbat.ac.kr6

7  Uniquely identifying traffic between the hosts  Two IP addresses and two port numbers  Source/destination IP address  Source/destination port  Underlying transport protocol (e.g., TCP or UDP) http://network.hanbat.ac.kr7 Connection socket pair (128.2.194.242:3479, 208.216.181.15:80) HTTP Server (port 80) Client Client socket address 128.2.194.242:3479 Server socket address 208.216.181.15:80 Client host address 128.2.194.242 Server host address 208.216.181.15 FTP Server (port 21)

8 Socket  Server and Client exchange messages over the network through a common Socket API http://network.hanbat.ac.kr8 TCP/UDP IP Ethernet Adapter Server TCP/UDP IP Ethernet Adapter Clients Socket API hardware kernel space user space ports Application Socket API TCPUDP...

9  struct sockaddr http://network.hanbat.ac.kr9  The generic: struct sockaddr { u_short sa_family; char sa_data[14]; };  sa_family specifies which address family is being used determines how the remaining 14 bytes are used  The Internet-specific: struct sockaddr_in { sin_family short sin_family; sin_port u_short sin_port; sin_addr struct in_addr sin_addr; char sin_zero[8]; };  sin_family = AF_INET (PF_INET)  sin_port: port # (0~65535)  sin_addr: IP address  sin_zero: unused struct in_addr { // IP addr. __be32 s_addr; // 32 bits };

10 Byte Ordering  What would happen if two computers with different integer byte ordering communicate? … different CPU  Example  sizeof(int)  4 http://network.hanbat.ac.kr10 89 67 F5 E4 D3 C2 B1 A0 Big-Endian Little-Endian 0 MAX address int * lptr; (* lptr) = 0x8967F5E4;(* lptr) = 0xE4F56789; lptr + 1 100 101 102 103

11 http://network.hanbat.ac.kr11 Big-Endian Little-Endian Motorola 68xx, 680x0 Intel IBM Hewlett-Packard DEC VAX Internet TCP/IP Sun SuperSPARC Bi-Endian Motorola Power PC Silicon Graphics MIPS RS 232 AMD

12  Introduction of a network byte order.  Big endian  uint16_thtons (uint16_thost16bitvalue)  uint32_thtonl (uint32_thost32bitvalue)  uint16_tntohs (uint16_tnet16bitvalue)  uint32_tntohl (uint32_tnet32bitvalue)  For port numbers and IP addresses http://network.hanbat.ac.kr12

13 Byte Manipulation Functions #include void bzero (void *dest, int n);  반환값 : 없음 void bcopy (const void *src, void *dest, int n);  반환값 : 없음 int bcmp (const void *ptr1, const void *ptr2, int n);  반환값 : 같으면 0, 같지 않으면 0 이 아닌 정수 http://network.hanbat.ac.kr13

14 #include void *memset (void *dest, int c, int n);  반환값 : 메모리 영역 dest 에 대한 포인터 void *memcpy (void *dest, const void *src, int n);  반환값 : 메모리 영역 dest 에 대한 포인터 int memcmp (const void *ptr1, const void *ptr2, int n);  반환값 : 같으면 0, 같지 않으면 음의 정수 또는 양의 정수 http://network.hanbat.ac.kr14

15 Address Conversion Functions  #include  int inet_aton (const char *strptr, struct in_addr *addrptr);  문자열 IP address (strptr) 를 in_addr 구조체로 변환  반환값 : 성공시 1, 에러시 0  in_addr_t inet_addr (const char *strptr);  문자열 IP addres (strptr) 를 network-byte order 의 바이너리 데이터 (in_addr_t 타입 ) 로 변경하여 리턴  반환값  성공시 32-bit network byte ordered IPv4 주소  에러시 INADDR_NONE  char *inet_ntoa (struct in_addr inaddr);  Network-byte order 의 바이너리 주소를 ( 문자열 ) IP address 로 변경  반환값 : dotted-decimal 문자열 포인터  ※ a = ascii, n = numeric http://network.hanbat.ac.kr15 “192.168.1.2”

16  int inet_pton (int af, const char *src, void *dst);  converts the character string src into a network address structure in the af address family. (IPv4, IPv6 지원 )  const char *inet_ntop (int af, const void *src, char *dst, socklen_t size);  converts the network address structure src in the af address family into a character string. (IPv4, IPv6 지원 ) #include void main(int argc, char *argv[]) { struct in_addr addr; char buf[20]; printf ("demical IP addr : %s\n", argv[1]); inet_pton (AF_INET, argv[1], &addr.s_addr); // “192.168.10.1”  binary printf ("inet_pton(%s) : 0x%x\n", argv[1], addr.s_addr); inet_ntop (AF_INET, &addr.s_addr, buf, sizeof(buf)); printf ("inet_ntop(0x%x) = %s\n", addr.s_addr, buf); } http://network.hanbat.ac.kr16 “192.168.1.2”

17 #include main() { struct sockaddr_in antelope; char *some_addr; inet_aton ("10.0.0.1", &antelope.sin_addr); // store IP in antelope some_addr = inet_ntoa (antelope.sin_addr); // return the IP printf ("%s\n", some_addr);// prints "10.0.0.1" // and this call is the same as the inet_aton() call, above: antelope.sin_addr.s_addr = inet_addr ("10.0.0.1"); } http://network.hanbat.ac.kr17

18 호스트 정보를 얻기 위한 함수 #include struct hostent *gethostbyname (const char *hostname);  문자열 hostname 의 노드에 대한 정보를 리턴 (struct hostent * 타입 )  “network.hanbat.ac.kr”  210.110.249.28 struct hostent { char*h_name;/* 공식적인 호스트 이름 */ char **h_aliases;/* 호스트의 별칭 목록 */ int h_addrtype;/* 호스트 주소 타입 : AF_INET or AF_INET6 */ int h_length;/* 호스트 주소의 길이 : IPv4 의 경우 4 */ char **h_addr_list;/* 호스트 주소 목록, numeric */ }; http://network.hanbat.ac.kr18

19 http://network.hanbat.ac.kr19 #include int main (int argc, char *argv[]) { int i; struct hostent *he; struct in_addr **addr_list;

20 http://network.hanbat.ac.kr20 if ((he = gethostbyname(argv[1])) == NULL) { herror("gethostbyname"); return 2; } printf("Official name is: %s\n", he->h_name); printf(" IP addresses: "); addr_list = (struct in_addr **)he->h_addr_list; for(i = 0; addr_list[i] != NULL; i++) { printf("%s \n", inet_ntoa(*addr_list[i])); } printf("\n"); } 실습 16, 17, 19~20

21  struct hostent *gethostbyaddr (const char *addr, int len, int family);  이진 IP 주소를 사용하여 그 주소에 해당하는 호스트 이름을 찾는다.  addr.  char * 타입이지만 사실은 in_addr 구조체의 포인터 주소이다  len.  IP 주소의 크기이다. IPv4 의 경우는 4  Family  주소 체계를 나타낸다. IPv4 의 경우는 AF_INET  202.30.46.38 (binary address)  “www.hanbat.ac.kr” http://network.hanbat.ac.kr21

22 http://network.hanbat.ac.kr22 #include int main (int argc, char *argv[]) { struct hostent *he; struct in_addr addr; inet_aton(argv[1], &addr); he = gethostbyaddr(&addr, sizeof(addr), AF_INET); printf("Host name: %s\n", he->h_name); }

23 #include int gethostname (char *retName, int namelen);  현재의 호스트 이름을 반환 http://network.hanbat.ac.kr23

24 http://network.hanbat.ac.kr24 #include main(int argc, char **argv) { char hostname[128]; gethostname(hostname, sizeof(hostname)); printf("My hostname: %s\n", hostname); } 실습 22, 24

25 http://network.hanbat.ac.kr25

26 #include main(int argc, char *argv[]) { struct in_addr ip; struct hostent *hostentry; char str[50]; if (argc != 2){ printf("Usage: address_conversion [ Ip address ]\n"); exit(0); } http://network.hanbat.ac.kr26

27 inet_aton(argv[1], &ip); printf("Dotted_decimal to Binary_IP = \t%X\n", ip); hostentry=gethostbyaddr((char *)&ip, sizeof(ip), AF_INET); printf("Binary_IP to Domain_name = \t%s\n", hostentry->h_name); memcpy(str, hostentry->h_name, strlen(hostentry->h_name)); // copy host name to str str[strlen(hostentry->h_name)] = '\0'; memset(hostentry, 0, sizeof(struct hostent));// clear hostentry memset(&ip, 0, sizeof(ip));// clear ip hostentry=gethostbyname(str); memcpy(&ip.s_addr, hostentry->h_addr_list[0], sizeof(ip.s_addr));// set ip.s_addr printf("Domain_name to Binary_IP = \t%X\n", ip); printf("Binary_IP to Dotted_decimal = \t%s\n", inet_ntoa(ip)); } http://network.hanbat.ac.kr27

28 http://network.hanbat.ac.kr28 실습

29 서비스 정보를 얻기 위한 함수 #include struct servent *getservbyname (const char *servname, const char *protoname);  반환값  성공시 호스트의 정보가 담긴 구조체 포인터  에러시 NULL struct servent *sptr; sptr = getservbyname (“domain”, “udp”); sptr = getservbyname (“ftp”, “tcp”); sptr = getservbyname (“ftp”, NULL); sptr = getservbyname (“ftp”, “udp”);// 에러. ftp 는 udp 를 사용하지 않는다 */ http://network.hanbat.ac.kr29 struct servent{ char *s_name;/* 공식적인 서비스 이름 */ char **s_aliases;/* 별칭 목록 */ int s_port;/* 포트번호, network-byte order */ char *s_proto;/* 사용되는 프로토콜 */ };

30 #include struct servent *getservbyport (int port, const char *protoname);  반환값  성공시 호스트의 정보가 담긴 구조체 포인터  에러시 NULL struct servent*sptr; sptr = getservbyport (htons(53), “udp”); sptr = getservbyport (htons(21), “tcp”); sptr = getservbyport (htons(21), NULL); sptr = getservbyport (htons(21), “udp”);// 에러. ftp 는 udp 를 사용하지 않는다 http://network.hanbat.ac.kr30

31 #include main(int argc, char *argv[]) { struct in_addr ip; struct servent *service; int port; if (argc != 3) { printf("Usage: getservice [service] [port]\n"); exit(0); } http://network.hanbat.ac.kr31

32 if ( (service = getservbyname(argv[1], NULL)) == NULL) { printf("getservbyname error\n"); exit(-1); } port = ntohs(service->s_port); printf("%s port number: %d(%s)\n", service->s_name, port, service->s_proto); memset(service, 0, sizeof(struct servent)); port = htons(atoi(argv[2])); if ((service = getservbyport(port, NULL)) == NULL) { printf("getservbyname error\n"); exit(-1); } printf("port %d(%s) : %s service\n", ntohs(service->s_port), service->s_proto, service->s_name ); } http://network.hanbat.ac.kr32 실습

33 SOCKET API http://network.hanbat.ac.kr33

34 전체 과정  above TCP http://network.hanbat.ac.kr34

35  Above UDP http://network.hanbat.ac.kr35

36 기본적인 소켓 함수들 #include int socket (int family, int type, int protocol);  Create socket  반환값 : 성공시 소켓 기술자, 에러시 -1  Familytype  Protocol  일반적으로 0 http://network.hanbat.ac.kr36 family 설 명 AF_INET AF_INET6 AF_LOCAL AF_ROUTE AF_KEY AF_ISO IPv4 protocols IPv6 protocols Unix domain protocols Routing sockets Key socket OSI protocols type 설 명 SOCK_STREAM SOCK_DGRAM SOCK_RAW Stream socket (TCP) Datagram socket (UDP) Raw socket Application Socket API TCPUDP...

37 #include int connect (int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);  Client 가 수행  Connect to server (in servaddr)  반환값 : 성공시 0, 에러시 -1 http://network.hanbat.ac.kr37

38 #include int bind (int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);  Server 가 실행  Bind address/port (in myaddr) to socket (in sockfd)  반환값 : 성공시 0, 에러시 -1  Wildcard 주소의 예 struct sockaddr_in servaddr; servaddr.sin_addr.s_addr = htonl (INADDR_ANY); /* wildcard */  자신의 IP 주소를 자동적으로 찾아줌  여러 개의 NIC 을 가지고 있는 경우  각 NIC 에는 하나씩의 IP 주소가 할당됨  이때, INADDR_ANY 는 모든 NIC 에 할당된 IP 주소들 전체를 의미 http://network.hanbat.ac.kr38

39  Many client requests may arrive  Server cannot handle them all at the same time  Server could reject the requests, or let them wait #include int listen (int sockfd, int backlog);  Server 가 실행  backlog  Define how many connections can be pending  Listen is non-blocking  returns immediately  반환값  성공시 0  에러시 -1 http://network.hanbat.ac.kr39

40  Server  Waits for connection request to arrive  Blocking until the request arrives  And then accepting the new request #include int accept (int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);  Server 가 실행  Accept a new connection from a client  반환값  새로운 연결소켓 기술자  에러시 -1  리턴 후,  cliaddr 에는 연결한 클라이언트의 주소 정보가 저장된다. http://network.hanbat.ac.kr40

41 #include int close (int sockfd);  (read, write 를 포함하는 ) sockfd 의 종료  반환값 : 성공시 0, 에러시 -1  int shutdown (int sockfd, int howto);  sockfd 의 종료  close 보다 미세한 조정 가능  Howto  SHUT_RD : 읽기만을 종료  SHUT_WR : 쓰기만을 종료  SHUT_RDWR : 읽기 / 쓰기 모두 종료  반환값 : 성공시 0, 에러시 -1 http://network.hanbat.ac.kr41

42 데이터의 송수신을 처리하기 위한 함수들 #include int write (int sockfd, const void *buff, int nbytes);  TCP  반환값 : 성공시 송신된 실제 바이트 수, 에러시 -1 #include int send (int sockfd, const void *buff, int nbytes, int flags);  TCP int sendto (int sockfd, const void *buff, int nbytes, int flags, const struct sockaddr *to, socklen_t addrlen);  UDP  반환값 : 성공시 송신된 실제 바이트 수, 에러시 -1 http://network.hanbat.ac.kr42

43  Flags  보통의 경우는 0 http://network.hanbat.ac.kr43 flags 설명 recv/send MSG_DONTROUTE 경로배정 처리를 하지 않는다.( 소켓 옵션참고 ) send MSG_DONTWAIT send, sendto, recv, recvfrom 함수에서 blocking 되지 않는다. recv/send MSG_OOB 대역외 데이터의 송수신시 사용된다. recv/send MSG_PEEK recv 혹은 recvfrom 함수 호출이 끝난 후 시스템이 데이터를 버리지 않고 살펴볼 수 있게 한다. recv MSG_WAITALL 수신 함수에 지정한 바이트만큼 읽기 전에는 함수에서 돌아오지 못하도록 지시한다. recv

44 #include int read (int sockfd, void *buff, int nbytes);  TCP  반환값 : 성공시 수신된 실제 바이트 수, 에러시 -1 #include int recv (int sockfd, void *buff, int nbytes, int flags);  TCP int recvfrom (int sockfd, void *buff, int nbytes, int flags, struct sockaddr *from, socklen_t *addrlen);  UDP  데이터가 수신되면, ( 데이터를 송신한 ) 상대방의 주소가 from 에 저장된다. http://network.hanbat.ac.kr44

45 TCP EXAMPLES http://network.hanbat.ac.kr45

46 Simple socket example  Basically the client connects to the server,  the server sends the message “Hello World”, and the client prints the received message. http://network.hanbat.ac.kr46 connection Client Server “Hello World” “Hello world”

47  simpleServer.c #include int main(){ int welcomeSocket, newSocket; char buffer[1024]; struct sockaddr_in serverAddr; struct sockaddr_in serverStorage; socklen_t addr_size; /*---- Create the socket. ----*/ welcomeSocket = socket(AF_INET, SOCK_STREAM, 0); http://network.hanbat.ac.kr47

48 /*---- Configure settings of the server address struct ----*/ serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(7891); serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); memset(serverAddr.sin_zero, '\0', sizeof (serverAddr.sin_zero)); /*---- Bind the address struct to the socket ----*/ bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr)); /*---- Listen on the socket, with 5 max connection requests queued ----*/ if(listen(welcomeSocket, 5)==0) printf("Listening\n"); else printf("Error\n"); http://network.hanbat.ac.kr48

49 /*---- Accept call creates a new socket for the incoming connection ----*/ addr_size = sizeof (serverStorage); newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size); /*---- Send message to the socket of the incoming connection ----*/ strcpy(buffer, "Hello World\n"); send(newSocket, buffer, 13, 0); } http://network.hanbat.ac.kr49

50  simpleClient.c #include int main(){ int clientSocket; char buffer[1024]; struct sockaddr_in serverAddr; socklen_t addr_size; /*---- Create the socket. ----*/ clientSocket = socket(AF_INET, SOCK_STREAM, 0); http://network.hanbat.ac.kr50

51 /*---- Configure settings of the server address struct ----*/ serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(7891); serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); memset(serverAddr.sin_zero, '\0', sizeof (serverAddr.sin_zero)); /*---- Connect the socket to the server using the address struct ----*/ addr_size = sizeof (serverAddr); connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size); /*---- Read the message from the server into the buffer ----*/ recv(clientSocket, buffer, 1024, 0); /*---- Print the received message ----*/ printf("Data received: %s", buffer); } http://network.hanbat.ac.kr51

52 http://network.hanbat.ac.kr52 실습

53 Iterative daytime 서버와 클라이언트 http://network.hanbat.ac.kr53 connection Client Server time Print time “connection from...” Get time

54 Iterative daytime 서버와 클라이언트  inet.h #include http://network.hanbat.ac.kr54

55  daytime server - daytime_ser_tcp.c #include "inet.h" #include #define MSGLEN 128 int main(int argc, char *argv[]) { int sockfd, confd; struct sockaddr_in servaddr, cliaddr; int len; char buf[MSGLEN]; time_t date; if (argc != 2) { printf("Usage: daytime_ser [Port number]\n"); exit(0); } http://network.hanbat.ac.kr55

56 if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ printf("server: can't create socket\n"); exit(-1); } servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* wild card */ servaddr.sin_port = htons(atoi(argv[1])); if ( (bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))) < 0){ printf("server: bind error\n"); exit(-1); } listen(sockfd, 5); http://network.hanbat.ac.kr56

57 while(1) { len = sizeof(cliaddr); confd = accept(sockfd, (struct sockaddr *)&cliaddr, &len); if (confd < 0) { printf("server: accept error\n"); exit(-1); } printf("connection from %s, port %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, buf, sizeof(buf)), ntohs(cliaddr.sin_port)); date = time(NULL);// date  the number of seconds since the 1970-01-01-0-0 memset(buf, '\0', sizeof(buf)); sprintf(buf, "%s", ctime(&date)); // buf  calendar time (“ Mon Aug 13 08:23:14 2012 “) send(confd, buf, strlen(buf), 0); close(confd); } http://network.hanbat.ac.kr57

58  daytime client - daytime_cli_tcp.c #include "inet.h" #include #define MSGLEN 128 int main(int argc, char *argv[]) { int sockfd, clifd; struct sockaddr_in servaddr; int len; char buf[MSGLEN]; time_t date; if (argc != 3){ printf("Usage: daytime_cli [Server IP] [Port number]\n"); exit(0); } http://network.hanbat.ac.kr58

59 if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ printf("client: can't create socket\n"); exit(-1); } memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = inet_addr(argv[1]);// server ip addr servaddr.sin_port = htons(atoi(argv[2]));// server port # if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0){ printf("client: can't connect\n"); exit(-1); } http://network.hanbat.ac.kr59

60 memset(buf, '\0', sizeof(buf)); while( (len=recv(sockfd, buf, MSGLEN, 0)) > 0){ buf[len]= '\0'; printf("%s", buf); } close(sockfd); } http://network.hanbat.ac.kr60

61 http://network.hanbat.ac.kr61 실습

62 Echo client/server http://network.hanbat.ac.kr62 connection Client Server echoed data Print Read from socket echo Read from KB data

63  echoServer.c /*Required Headers*/ #include int main() { char str[100]; int listen_fd, comm_fd; struct sockaddr_in servaddr; http://network.hanbat.ac.kr63

64 listen_fd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(22000); bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr)); listen(listen_fd, 10); comm_fd = accept(listen_fd, (struct sockaddr*) NULL, NULL); http://network.hanbat.ac.kr64

65 while (1) { bzero(str, 100); read(comm_fd, str, 100); printf("Echoing back - %s", str); write(comm_fd, str, strlen(str)+1); } http://network.hanbat.ac.kr65

66  echoClient.c #include int main(int argc,char **argv) { int sockfd,n; char sendline[100]; char recvline[100]; struct sockaddr_in servaddr; sockfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof (servaddr)); http://network.hanbat.ac.kr66

67 servaddr.sin_family = AF_INET; servaddr.sin_port = htons(22000); inet_pton(AF_INET, "127.0.0.1", &(servaddr.sin_addr)); connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); while(1) { bzero(sendline, 100); bzero(recvline, 100); fgets(sendline, 100, stdin); /*stdin = 0, standard input */ write(sockfd, sendline, strlen(sendline)+1); read(sockfd, recvline, 100); printf("%s", recvline); } http://network.hanbat.ac.kr67

68  execution http://network.hanbat.ac.kr68 실습

69 과제  클라이언트와 서버 프로세스간 1:1 로 통신하는 채팅 프로그램을 작성하라.  클라이언트가 키보드로 입력한 메시지는 서버에게 출력되고, 서버가 키보드로 입력한 메시지는 클라이언트에게 출력된다.  클라이언트와 서버는 번갈아 가면서 메시지를 입력한다. http://network.hanbat.ac.kr69

70 http://network.hanbat.ac.kr70 connection Client Server data Print read data Read from KB data 실습

71  chatServer.c #include int main(int argc, char *argv[]) { int socket_desc, client_sock, c, read_size, portno; struct sockaddr_in server, client; char client_message[100], msg[100]; http://network.hanbat.ac.kr71

72 if (argc < 2) { printf("chatServer port#\n"); exit(0); } portno = atoi(argv[1]); bzero((char *) &server, sizeof(server)); //Create socket socket_desc = socket(AF_INET, SOCK_STREAM, 0); if (socket_desc == -1) { printf("Could not create socket"); } //Prepare the sockaddr_in structure server.sin_family = AF_INET; server.sin_addr.s_addr = htonl(INADDR_ANY); server.sin_port = htons(portno); http://network.hanbat.ac.kr72

73 //Bind if (bind(socket_desc, (struct sockaddr *) &server, sizeof(server)) < 0) { perror("bind failed. Error"); return 1; } listen(socket_desc, 3); printf("Waiting for incoming connections...\n"); c = sizeof(struct sockaddr_in); //accept connection from an incoming client client_sock = accept(socket_desc, (struct sockaddr *) &client, (socklen_t *) & c); if (client_sock < 0) { perror("accept failed"); return 1; } printf("Connection accepted\n"); http://network.hanbat.ac.kr73

74 //Receive a message from client bzero(&client_message, sizeof(client_message)); while ((read_size = recv(client_sock, client_message, 100, 0)) > 0) { printf("Client message: %s", client_message); printf("Enter msg to sent to client: "); bzero(&msg, sizeof(msg)); fgets(msg, 100, stdin); //Send the message back to client if (write(client_sock, msg, sizeof(msg)) < 0) { puts("Sorry message failed, Client disconnected"); break; } bzero(&client_message, sizeof(client_message)); } http://network.hanbat.ac.kr74

75 if (read_size == 0) { puts("Client disconnected"); fflush(stdout); } else if (read_size == -1) { perror("recv failed"); } return 0; } http://network.hanbat.ac.kr75

76  chatClient.c #include int main(int argc, char *argv[]) { int sock, portno; struct sockaddr_in server; struct hostent *host; char message[100], server_reply[100]; if (argc < 3) { printf("chatClient serverIP serverPort\n"); exit(0); } http://network.hanbat.ac.kr76

77 portno = atoi(argv[2]); host = gethostbyname(argv[1]); if (!host) { herror(argv[1]); exit(-1); } //Create socket sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == -1) { printf("Could not create socket"); } puts("Socket created"); server.sin_addr.s_addr = *(long *) (host->h_addr); server.sin_family = AF_INET; server.sin_port = htons(portno); http://network.hanbat.ac.kr77

78 //Connect to remote server if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) { perror("connect failed. Error"); return 1; } printf("Connected\n"); printf("Enter message: "); bzero(&message, sizeof(message)); fgets(message, 100, stdin); //Send some data if (send(sock, message, strlen(message), 0) < 0) { puts("Send failed"); return 1; } bzero(&server_reply, sizeof(server_reply)); http://network.hanbat.ac.kr78

79 //Receive a reply from the server while (recv(sock, server_reply, 100, 0) > 0) { printf("Server reply : %s", server_reply); bzero(&server_reply, sizeof(server_reply)); printf("Enter message('bye' to quit): "); bzero(&message, sizeof(message)); fgets(message, 100, stdin); if (strcmp(message, "bye\n") == 0) break; if (send(sock, message, strlen(message), 0) < 0) { puts("Send failed"); return 1; } close(sock); return 0; } http://network.hanbat.ac.kr79

80 http://network.hanbat.ac.kr80 실습

81 FILE IO http://network.hanbat.ac.kr81

82 기본 내용  파일  하드디스크에 저장되어 있음  응용 프로세스 (process) 에서 바이트 단위로 입출력  파일에서 데이터를 읽고 쓸 때의 과정  파일을 열고  fopen  열린 파일의 데이터를 읽거나 쓰고  fscanf, fprintf  파일을 닫음  fclose  다 사용한 후에 82 HD HW OS (Kernel) APP.

83 File open FILE *fopen ( const char *filename, const char *mode );  filename  읽거나 쓸 파일의 이름  mode  “r”  읽기 (read) 모드로 파일을 연다.  파일이 없으면 에러가 발생하고, NULL 값을 돌려준다.  파일이 있으면, marker 가 파일의 첫 부분을 가리킨다. marker: 다음에 읽을 위치  파일 오픈 후, 파일에 쓰려고 하면 에러 발생  “w”  쓰기 (write) 모드로 파일을 연다.  파일이 없으면 새로 만든다.  기존의 파일이 있으면 그 이전의 내용은 삭제된다.  Marker 는 파일의 첫 부분을 가리킴.  파일 오픈 후, 파일에서 읽으려고 하면 에러 발생  “r+” 또는 “w+” : 읽거나 쓰기 용으로 open 83

84  “a”  추가 쓰기 (append) 모드로 파일을 연다.  파일이 없으면 새로 만든다.  기존의 파일이 있으면 marker 가 파일의 끝을 가리킨다  새로 추가되는 내용은 그 파일의 가장 뒤부터 파일에 추가한다.  파일 오픈 후, 파일에서 읽으려고 하면 에러 발생  Return 값  성공시 : FILE *  실패시 : NULL  예 : 없는 파일을 읽기 모드로 여는 경우  man fopen  예 #include FILE *fp; fp = fopen (“temp.dat”, “w”); 84

85 File close  파일에 대한 쓰기, 읽기 등의 작업이 종료된 후 int fclose ( FILE *fp );  fp 는 fopen () 이 리턴했던 파일 포인터  리턴값 0 은 성공적으로 닫았음을 나타냄  오류가 발생하면, 이 함수는 EOF 를 리턴 85

86 open/close 전체 예 #include int main (void) { FILE *fp; if ((fp=fopen("basic.txt", "w")) == NULL) { printf (“File open failed. \n"); } // write code... if (fclose(fp) == EOF) { printf("Error closing basic.txt\n"); } return 0; }  프로그램이 정상적으로 실행된 경우  basic.txt 파일이 생성됨 86

87 fprintf #include int main ( void ) { FILE *fp; if ((fp=fopen("basic.txt", "w")) == NULL) { printf ("The file (basic.txt) is not opened. \n"); } fprintf(fp, "My code name is %c, my code is %d.\n", 'Z', 123); if (fclose(fp) == EOF) { printf("Error closing basic.txt\n"); } return 0; } 87 실습

88 fscanf #include int main (void) { FILE *fp; char ch; int ret; if ((fp=fopen("basic.txt", "r")) == NULL) { printf ("The file ( basic.txt ) is not opened. \n"); } do { ret = fscanf (fp, "%c", &ch); // fscanf 는 읽은 항목 수를 리턴 if (ret == EOF)// file 의 끝까지 읽은 후에는 EOF 를 리턴 break; printf ("%c", ch); } while (1); if (fclose(fp) == EOF) { printf("Error closing basic.txt\n"); } return 0; } 88 실습

89 #include int main (void) { FILE *fp; char str[128]; int ret; if ((fp=fopen("basic.txt", "r")) == NULL) { printf ("The file ( basic.txt ) is not opened. \n"); } do { ret = fscanf (fp, "%s", str); if (ret == EOF) break; printf ("%s\n", str); } while (1); if (fclose(fp) == EOF) { printf("Error closing basic.txt\n"); } return 0; } 89

90 과제  간단한 파일전송 클라이언트 - 서버 (simple FTP)  클라이언트는 서버에게 자신이 원하는 파일 이름을 전송한다.  서버는 클라이언트로부터 수신한 파일이름의  파일 내용을 읽어서, 클라이언트에게 전송한다.  클라이언트는 서버로부터 수신되는 파일 내용을 자신의 하드디스크에 저장한다. 90

91 91 connection Client Server File data Save file contents Read file data Write file data File name “file name” 과제

92 IO BLOCKING http://network.hanbat.ac.kr92

93 문제점  서버가 n 개의 client 프로세스와 통신을 하는 경우  어느 클라이언트에서 데이터가 송신될지는 알 수 없는 경우  서버가 1 번 클라이언트에서 read 하면  1 번은 데이터를 송신하지 않은 경우  서버 blocking  3 번은 데이터를 송신하였음  서버가 이미 1 번 클라이언트로부터 데이터를 읽기 위해서 blocking 되었으므로, 읽혀지지 않음  1 번이 데이터를 보낼 때까지 서버는 blocking  해결방안  Non-blocking read  Read loop, fcntl() with O_NONBLOCK  select (2) http://network.hanbat.ac.kr93

94 select(2): I/O Multiplexing  Waits on multiple file descriptors and timeout  The select() system call allows us to use blocking I/O on a set of descriptors (file, socket, …).  For example, we can ask select to notify us when data is available for reading on either STDIN or a TCP socket.  Returns when any file descriptor is  ready to be read or  written or  indicate an error, or  timeout exceeded  advantages  simple  application does not consume CPU cycles while waiting http://network.hanbat.ac.kr94

95 #include int select (int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout);  maxfdp1  descriptors (0, 1,... maxfds-1) will be tested  보통 가장 큰 소켓번호에 1 을 더하여 사용  readset  a set of fds we want to check if data is available  returns a set of fds ready to read  writeset  returns a set of fds ready to write  exceptset  returns a set of fds with exception conditions http://network.hanbat.ac.kr95

96  Timeout  if NULL, wait forever and return only when one of the descriptors is ready for I/O  otherwise, wait up to a fixed amount of time specified by timeout  if we don’t want to wait at all, create a timeout structure with timer value equal to 0 struct timeval { longtv_sec;/* seconds */ longtv_usec;/* microseconds */ }; /* 0.5 초 동안 sleep 하는 코드 */ struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 500000; /* 0.5 초 */ select(0, NULL, NULL, NULL, &timeval); http://network.hanbat.ac.kr96

97  반환값  성공시  감지된 소켓기술자의 수  타임아웃시 0  에러시 -1 http://network.hanbat.ac.kr97

98  fd_set 집합을 다루기 위해 사용되는 4 개의 매크로 http://network.hanbat.ac.kr98 매크로설명 void FD_ZERO (fd_set *fdset); fdset 의 모든 비트를 지운다. void FD_SET (int fd, fd_set *fdset) fdset 중 소켓 fd 에 해당하는 비트를 on(1) 시킨다 void FD_CLR (int fd, fd_set *fdset); fdset 중 소켓 fd 에 해당하는 비트를 off(0) 시킨다 int FD_ISSET (int fd, fd_set *fdset); fdset 중 소켓 fd 에 해당하는 비트가 on 되어 있으면 양수값을 반환한다

99  Pseudo code int s1, s2; /* socket descriptors */ fd_set readfds;/* used by select() */ /* create and bind s1 and s2 */ http://network.hanbat.ac.kr99

100 while(1) { FD_ZERO(&readfds);/* initialize the fd set */ FD_SET(s1, &readfds);/* add s1 to the fd set */ FD_SET(s2, &readfds);/* add s2 to the fd set */ if(select(s2+1, &readfds, 0, 0, 0) < 0) { perror(“select”); exit(1); } if(FD_ISSET(s1, &readfds)) { recvfrom(s1, buf, sizeof(buf),...); /* process buf */ } /* do the same for s2 */ } http://network.hanbat.ac.kr100

101 select 함수의 사용 예  select 함수를 사용한 TCP Concurrent echo 서버 - 클라이언트 http://network.hanbat.ac.kr101

102  echo_ser_tcp_select.c #include "inet.h" #include #define MSGLEN 1024 #define MAXCLI 50 int main(int argc, char *argv[]) { int sockfd, confd; struct sockaddr_in cliaddr, servaddr; int addrlen; fd_set read_fdset; http://network.hanbat.ac.kr102

103 int client_fd[MAXCLI]; int client_num = 0; char buf[MSGLEN]; int msg_len, maxfdp1, nready, i; pid_t childpid; if (argc != 2){ printf("Usage:echo_ser_select [Port number]\n"); exit(0); } if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ printf("server: can't create socket\n"); exit(-1); } http://network.hanbat.ac.kr103

104 servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* wild card */ servaddr.sin_port = htons(atoi(argv[1])); if ((bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))) < 0){ printf("server: bind error\n"); exit(-1); } listen(sockfd, 5); for (i=0; i<MAXCLI; i++) client_fd[i] = -1; FD_ZERO(&read_fdset); maxfdp1 = sockfd + 1; http://network.hanbat.ac.kr104

105 while(1) { FD_SET(sockfd, &read_fdset); for (i=0; i<MAXCLI; i++){ if (client_fd[i] != -1) FD_SET(client_fd[i], &read_fdset); } if ((nready=select(maxfdp1, &read_fdset, NULL, NULL, NULL) )< 0){ printf("select error..\n"); exit(-1); } http://network.hanbat.ac.kr105

106 if (FD_ISSET(sockfd, &read_fdset)){ addrlen = sizeof(cliaddr); confd=accept(sockfd,(struct sockaddr *)&cliaddr, &addrlen); if (confd < 0){ printf("server: accept error\n"); exit(-1); } if (client_num >= MAXCLI) { printf(“too many clients\n”); close(confd); continue; } printf("connection new client(confd=%d)...\n", confd); for (i=0; i<MAXCLI; i++) { if (client_fd[i] != -1) continue; client_fd[i] = confd;maxfdp1++; client_num++;break; } http://network.hanbat.ac.kr106

107 for ( i=0; i<MAXCLI; i++) { if (client_fd[i] == -1) continue; if (FD_ISSET(client_fd[i], &read_fdset)) { memset(buf, '\0', sizeof(buf)); msg_len = read(client_fd[i], buf, MSGLEN); if ( write(client_fd[i], buf, msg_len) != msg_len ) { printf("server: write error!!\n"); close(confd); exit(0); } if ( --nready <= 0) /* 더 이상 변화된 소켓기술자가 없다면 */ break; } } /* end of the 'while' */ } http://network.hanbat.ac.kr107

108 http://network.hanbat.ac.kr108  echo_cli_tcp_select.c #include "inet.h" #include #define MSGLEN 1024 int main(int argc, char *argv[]) { int sockfd; struct sockaddr_in servaddr; fd_set read_fdset, reset; char buf[MSGLEN]; int len, msg_len, rcvlen, maxfdp1; if (argc != 3) { printf("Usage: echo_cli_select [Server IP] [Port number]\n"); exit(0); }

109 http://network.hanbat.ac.kr109 if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ printf("client: can't create socket\n"); exit(-1); } memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = inet_addr(argv[1]); servaddr.sin_port = htons(atoi(argv[2])); if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0){ printf("client: can't connect\n"); exit(-1); }

110 http://network.hanbat.ac.kr110 FD_ZERO(&read_fdset); FD_SET(0, &read_fdset); FD_SET(sockfd, &read_fdset); reset = read_fdset; maxfdp1 = sockfd + 1;

111 http://network.hanbat.ac.kr111 while(1){ read_fdset = reset; if (select(maxfdp1, &read_fdset, NULL, NULL, NULL) < 0) { printf("select error..\n"); exit(-1); } if (FD_ISSET(0, &read_fdset)){ memset(buf, '\0', sizeof(buf)); if ( (msg_len = read(0, buf, sizeof(buf))) <= 0) { close(sockfd);exit(0); } if ( write(sockfd, buf, msg_len) != msg_len ) { printf("client: write error!!\n"); close(sockfd); exit(0); }

112 http://network.hanbat.ac.kr112 if (FD_ISSET(sockfd, &read_fdset)) { memset(buf, '\0', sizeof(buf)); len=0; do { if ((rcvlen=read(sockfd,&buf[len],msg_len-len)) <= 0){ close(sockfd); exit(0); } len += rcvlen; } while(len < msg_len); printf("echo : %s", buf); }

113 http://network.hanbat.ac.kr113

114 UDP EXAMPLES http://network.hanbat.ac.kr114

115 UDP echo client/server http://network.hanbat.ac.kr115 Client Server echoed data Print Read from socket echo Read from KB data

116 UDP echo client/server  udpEchoServer.c #include #define BUFLEN 512 //Max length of buffer #define PORT 8888 //The port on which to listen for incoming data void die (char *s) { perror(s); exit(1); } http://network.hanbat.ac.kr116

117 int main(void) { struct sockaddr_in si_me, si_other; int s, i, slen = sizeof(si_other), recv_len; char buf[BUFLEN]; if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { die("socket"); } memset((char *) &si_me, 0, sizeof(si_me)); si_me.sin_family = AF_INET; si_me.sin_port = htons(PORT); si_me.sin_addr.s_addr = htonl(INADDR_ANY); if( bind(s, (struct sockaddr*)&si_me, sizeof(si_me) ) == -1) { die("bind"); } http://network.hanbat.ac.kr117

118 while(1) { printf("Waiting for data..."); fflush(stdout); //try to receive some data, this is a blocking call if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen)) == -1) { die("recvfrom()"); } buf[recv_len] = 0;// set null char. //print details of the client/peer and the data received printf("Received packet from %s:%d\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port)); printf("Data: %s\n", buf); http://network.hanbat.ac.kr118

119 //now reply the client with the same data if (sendto(s, buf, recv_len, 0, (struct sockaddr*) &si_other, slen) == -1) { die("sendto()"); } }// while close(s); return 0; } http://network.hanbat.ac.kr119

120  udpEchoClient.c #include #define SERVER "127.0.0.1" #define BUFLEN 512 //Max length of buffer #define PORT 8888 //The port on which to send data void die(char *s) { perror(s); exit(1); } http://network.hanbat.ac.kr120

121 main(void) { struct sockaddr_in si_other;int s, i, slen=sizeof(si_other); char buf[BUFLEN];char message[BUFLEN]; if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { die("socket"); } memset((char *) &si_other, 0, sizeof(si_other)); si_other.sin_family = AF_INET; si_other.sin_port = htons(PORT); if (inet_aton(SERVER, &si_other.sin_addr) == 0) { fprintf(stderr, "inet_aton() failed\n"); exit(1); } http://network.hanbat.ac.kr121

122 while(1) { printf("Enter message : ");fgets(message, 512, stdin); if (sendto(s, message, strlen(message), 0, (struct sockaddr *) &si_other, slen)==-1) { die("sendto()"); } //clear the buffer by filling null, it might have previously received data memset(buf, '\0', BUFLEN); //try to receive some data, this is a blocking call if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen) == -1) { die("recvfrom()"); } puts(buf); } http://network.hanbat.ac.kr122

123 close(s); return 0; } http://network.hanbat.ac.kr123

124 http://network.hanbat.ac.kr124 실습

125 Iterative echo 서버와 클라이언트 http://network.hanbat.ac.kr125

126 http://network.hanbat.ac.kr126  echo_ser_iter_udp.c #include "inet.h" #define MSGLEN 128 int main(int argc, char *argv[]) { int sockfd; struct sockaddr_in servaddr, cliaddr; int addrlen, msg_len; char clidot[20], buf[MSGLEN]; time_t date; if (argc != 2){ printf("Usage: echo_ser_iter_udp [Port number]\n"); exit(0); }

127 http://network.hanbat.ac.kr127 if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){ printf("server: can't create socket\n"); exit(-1); } servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* wild card */ servaddr.sin_port = htons(atoi(argv[1])); if ( (bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))) < 0){ printf("server: bind error\n"); exit(-1); }

128 http://network.hanbat.ac.kr128 while(1) { memset(buf, '\0', sizeof(buf)); addrlen = sizeof(cliaddr); msg_len = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&cliaddr, &addrlen); if (msg_len < 0) continue; printf("client: %s, port %d message length: %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, clidot, sizeof(clidot)), ntohs(cliaddr.sin_port), msg_len); if (sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr))!= msg_len) printf("sendto error\n"); }

129 http://network.hanbat.ac.kr129  echo_cli_udp.c #include "inet.h" #include #define MSGLEN 128 int main(int argc, char *argv[]) { int sockfd, clifd;struct sockaddr_in servaddr; fd_set read_fdset, reset; int addrlen, len, msg_len, maxfdp1; char buf[MSGLEN]; time_t date; if (argc != 3){ printf("Usage: echo_cli_dup [Server IP] [Port number]\n"); exit(0); }

130 http://network.hanbat.ac.kr130 if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){ printf("client: can't create socket\n"); exit(-1); } memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = inet_addr(argv[1]); servaddr.sin_port = htons(atoi(argv[2])); FD_ZERO(&read_fdset); FD_SET(0, &read_fdset); FD_SET(sockfd, &read_fdset); reset = read_fdset; maxfdp1 = sockfd + 1;

131 http://network.hanbat.ac.kr131 while(1){ read_fdset = reset; if (select(maxfdp1, &read_fdset, NULL, NULL, NULL) < 0){ printf("select error..\n"); exit(-1); }

132 http://network.hanbat.ac.kr132 if (FD_ISSET(0, &read_fdset)){ memset(buf, '\0', sizeof(buf)); if ( (msg_len = read(0, buf, sizeof(buf))) <= 0){ close(sockfd); exit(0); } if (sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&servaddr, sizeof(servaddr)) != msg_len){ printf("sendto error\n"); close(sockfd); exit(-1); }

133 http://network.hanbat.ac.kr133 if (FD_ISSET(sockfd, &read_fdset)){ memset(buf, '\0', sizeof(buf)); addrlen = sizeof(servaddr); len = recvfrom(sockfd, buf, MSGLEN, 0,(struct sockaddr *) &servaddr, &addrlen); printf("echo : %s", buf); } } /* end of the ‘while’ */ }

134 http://network.hanbat.ac.kr134

135 Concurrent echo 서버 http://network.hanbat.ac.kr135

136 http://network.hanbat.ac.kr136  echo_ser_con_udp.c #include "inet.h" #define MSGLEN 128 int main(int argc, char *argv[]) { int sockfd; struct sockaddr_in servaddr, cliaddr; int addrlen, msg_len; char clidot[20], buf[MSGLEN]; time_t date; if (argc != 2) { printf("Usage: echo_ser_iter_udp [Port number]\n"); exit(0); }

137 http://network.hanbat.ac.kr137 if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){ printf("server: can't create socket\n"); exit(-1); } servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* wild card */ servaddr.sin_port = htons(atoi(argv[1])); if ( (bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))) < 0){ printf("server: bind error\n"); exit(-1); }

138 http://network.hanbat.ac.kr138 while(1) { memset(buf, '\0', sizeof(buf)); addrlen = sizeof(cliaddr); msg_len = recvfrom (sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&cliaddr, &addrlen); if (msg_len < 0) continue; if (fork() == 0){ printf("client: %s, port %d message length: %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, clidot, sizeof(clidot)), ntohs(cliaddr.sin_port), msg_len); if (sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr))!= msg_len) printf("sendto error\n"); return 0; } /* end of the ‘child’ */ } /* end of the 'while' */ }

139 http://network.hanbat.ac.kr139


Download ppt "Network Programming:"

Similar presentations


Ads by Google