Download presentation
Presentation is loading. Please wait.
Published byCharleen Quinn Modified over 9 years ago
1
240-322 Cli/Serv.: sockets 3/91 Client/Server Distributed Systems v Objectives –describe iterative clients and servers using the UDP protocol 240-322, Semester 1, 2005-2006 9. Sockets (3)
2
240-322 Cli/Serv.: sockets 3/92 Overview 1. Why use UDP? 2. The UDP Protocol 3. A Connectionless Example 4. A Client for the UDP daytime Service
3
240-322 Cli/Serv.: sockets 3/93 1. Why use UDP? v The connectionless protocol, UDP, has two big drawbacks: –datagrams may arrive in any order –datagrams may be lost v TCP does not have these problems, so why use UDP?
4
240-322 Cli/Serv.: sockets 3/94 v UDP is reliable over a LAN –it is very unlikely that datagrams will be lost or reordered unless there is a hardware problem v UDP is less resource-intensive than TCP v Use UDP if the client-server communication is simple, such as: –get finger information from a server –get time/day information –messages must be small and self-contained
5
240-322 Cli/Serv.: sockets 3/95 2. The UDP Protocol socket() bind() recvfrom() blocks until data received from a client process request sendto() socket() bind() recvfrom() data (request) data (reply) sendto() Server Client
6
240-322 Cli/Serv.: sockets 3/96 Notes v The system calls for reading and writing are different from TCP. The client does not need to connect with the server using connect() (although it is possible). The server does not need to call accept().
7
240-322 Cli/Serv.: sockets 3/97 Communication Diagram server client
8
240-322 Cli/Serv.: sockets 3/98 sendto() Send a message from a socket to an address: Send a message from a socket to an address: #include #include int sendto(int sd, char *msg, int len, int flags, struct sockaddr *addr, int addrlen); v Return the length of the sent message if ok, -1 on error.
9
240-322 Cli/Serv.: sockets 3/99 sendto() Diagram sendto(sd, msg, len, flags, addr, addrlen); socket descriptor len data to be sent special delivery options; usually 0 addrlen address of destination
10
240-322 Cli/Serv.: sockets 3/910 recvfrom() Receive a message at a socket from an address: Receive a message at a socket from an address: #include #include int recvfrom(int sd, char *msg, int len, int flags, struct sockaddr *addr, int *addrlen); v Return the length of the received message if ok, -1 on error.
11
240-322 Cli/Serv.: sockets 3/911 recvfrom() Diagram n = recvfrom(sd, msg, len, flags, addr, &addrlen); socket descriptor len received data placed here special options; usually 0 addrlen address of sender n
12
240-322 Cli/Serv.: sockets 3/912 Other send/receive Functions #include #include int send(int sd, char *msg, int len, int flags); int recv(int sd, char *msg, int len, int flags); int sendmsg(int sd, struct msghdr msg[], int flags); int recvmsg(int sd, struct msghdr msg[], int flags);
13
240-322 Cli/Serv.: sockets 3/913 send() and recv() are used when the client has used connect() to specify its server –may not be supported in the future sendmsg() supports gather-write –collect data from different places in memory, and send as a single datagram recvmsg() supports scatter-read –split received datagram into separate places in memory
14
240-322 Cli/Serv.: sockets 3/914 3. A Connectionless Example 3.1. A UDP echo Server 3.2. A UDP echo Client 3.3. Usage
15
240-322 Cli/Serv.: sockets 3/915 3.1. A UDP echo Server Receive a string (ending in ‘\n’ ) from a client, convert it to uppercase, and send it back. v A simple communication protocol. v Messages are short and self-contained.
16
240-322 Cli/Serv.: sockets 3/916 echo_userv.c #include : /* usual includes */ #include /* for toupper() */ #define PORT 3667 #define BUFSIZE 128 void touppers(char buf[]); int udp_serv_sock(int port); :
17
240-322 Cli/Serv.: sockets 3/917 int main() { int sd, client_len, n; struct sockaddr_in client; char msg[BUFSIZE+1]; sd = udp_serv_sock(PORT); while(1) { client_len = sizeof(client); n = recvfrom(sd, msg, BUFSIZE, 0, (struct sockaddr *)&client, &client_len); :
18
240-322 Cli/Serv.: sockets 3/918 if (n < 0) fprintf(stderr, "recvfrom failed\n"); else { /* msg[n] = '\0'; printf("n: %d, msg: \"%s\"\n", n, msg); */ touppers(msg); if (sendto(sd, msg, n, 0, (struct sockaddr *)&client, client_len) != n) fprintf(stderr, "sendto error\n"); } } return 0; }
19
240-322 Cli/Serv.: sockets 3/919 int udp_serv_sock(int port) /* Bind a socket with the server's address using the UDP protocol. */ { int sockfd; struct sockaddr_in serv_addr; /* create a UDP socket */ if ((sockfd = socket(AF_INET,SOCK_DGRAM,0)) < 0) { fprintf(stderr, "Could not open a socket"); exit(1); } :
20
240-322 Cli/Serv.: sockets 3/920 /* initialise socket address */ memset((char *)&serv_addr, 0,sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(port); /* bind socket to address */ if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { fprintf(stderr, "Could not bind socket to address\n"); exit(1); } return sockfd; }
21
240-322 Cli/Serv.: sockets 3/921 Notes main() reads the client information from the recvfrom() call. Then it knows where to send the reply with sendto(). udp_serv_sock() is the same as tcp_serv_sock() (part 7, slide 10) except for the socket() type, and no listen() call. We cannot test this server with telnet because telnet uses the TCP protocol.
22
240-322 Cli/Serv.: sockets 3/922 3.2. A UDP echo Client v Read server details from the command line: $./echo_ucli takasila 3667 main() reads a line from stdin, sends it to the UDP echo server, and then prints the reply to stdout. The program continues until the user types EOF ( control-D ).
23
240-322 Cli/Serv.: sockets 3/923 echo_ucli.c #include : /* usual includes */ #include #define PORT 3667 #define BUFSIZE 128 struct sockaddr_in get_addr(int argc, char *argv[]); int open_udp_sock(void); :
24
240-322 Cli/Serv.: sockets 3/924 int main(int argc, char *argv[]) { struct sockaddr_in serv_addr; int sd, serv_len, n; char buf[BUFSIZE+1]; serv_addr = get_addr(argc, argv); serv_len = sizeof(serv_addr); sd = open_udp_sock(); :
25
240-322 Cli/Serv.: sockets 3/925 while (fgets(buf, BUFSIZE, stdin) != NULL) { n = strlen(buf); if (sendto(sd, buf, n, 0, (struct sockaddr *)&serv_addr, serv_len) != n) fprintf(stderr, "sendto failed\n"); else { if ((n = recvfrom(sd, buf, BUFSIZE, 0, (struct sockaddr *)0, (int *)0)) < 0) fprintf(stderr, "recvfrom failed\n"); else { buf[n] = '\0'; fputs(buf, stdout); } } } close(sd); return 0; }
26
240-322 Cli/Serv.: sockets 3/926 int open_udp_sock(void) /* Bind to any local address */ { int sd; struct sockaddr_in addr; if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { fprintf(stderr, "socket() error\n"); exit(1); } :
27
240-322 Cli/Serv.: sockets 3/927 memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(0); if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { fprintf(stderr, "Can not bind local address\n"); exit(1); } return sd; }
28
240-322 Cli/Serv.: sockets 3/928 Notes get_addr() is taken from part 7, slide 77. open_udp_sock() attaches any free port (between 1024-5000) to the socket by using 0 as the port value. –this port is used by the server when it replies
29
240-322 Cli/Serv.: sockets 3/929 3.3. Usage v v $./echo_userv &/* on takasila */ [1] 1745 $ netstat -a | grep 3667 udp 0 0 *:3667 *:* v v $./echo_ucli takasila /*on fivedots*/ hello HELLO good bye GOOD BYE $ control-D typed FT
30
240-322 Cli/Serv.: sockets 3/930 4. A Client for the UDP daytime Service The daytime service can be contacted by using TCP or UDP. Shown in /etc/services : : daytime 13/tcp daytime 13/udp It's also necessary to check /etc/inet.conf to see if the service is switched on –usually most UDP services are disabled due to hacker attack weaknesses continued
31
240-322 Cli/Serv.: sockets 3/931 v The availability of the service via TCP can be checked with telnet: –telnet 13 Execute the daytime UDP client (called day_cus ) with the server’s hostname as a command line argument: $./day_cus calvin
32
240-322 Cli/Serv.: sockets 3/932 day_cus.c #include : /* usual includes */ #include #define MSG ”\n" /* dummy 'wake-up' msg */ #define BUFSIZE 128 struct sockaddr_in get_udp_serv_addr(char *host, char *service); int open_udp_sock(void); :
33
240-322 Cli/Serv.: sockets 3/933 int main(int argc, char *argv[]) { struct sockaddr_in serv_addr; int sd, serv_len, n; char buf[BUFSIZE+1]; serv_addr = get_udp_serv_addr(argv[1], "daytime"); serv_len = sizeof(serv_addr); sd = open_udp_sock(); n = strlen(MSG); :
34
240-322 Cli/Serv.: sockets 3/934 if (sendto(sd, MSG, n, 0, (struct sockaddr *)&serv_addr, serv_len) != n) fprintf(stderr, "sendto failed\n"); else { if ((n = recvfrom(sd, buf, BUFSIZE, 0, (struct sockaddr *)0, (int *)0)) < 0) fprintf(stderr, "recvfrom failed\n"); else { buf[n] = '\0'; fputs(buf, stdout); } } close(sd); return 0; }
35
240-322 Cli/Serv.: sockets 3/935 struct sockaddr_in get_udp_serv_addr(char *host, char *service) /* Build a socket address struct for a system service using the host name (given in dotted-decimal or dotted-name format) and the service name. */ { struct sockaddr_in addr; unsigned long lgaddr; struct hostent *hp; struct servent *sp; if ((sp = getservbyname(service, "udp")) == NULL) { fprintf(stderr, "Unknown service\n"); exit(1); } :
36
240-322 Cli/Serv.: sockets 3/936 memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = sp->s_port; if ((lgaddr = inet_addr(host)) != -1) addr.sin_addr.s_addr = lgaddr; else if ((hp = gethostbyname(host)) != NULL) memcpy(&addr.sin_addr.s_addr, hp->h_addr, hp->h_length); else { fprintf(stderr, "Unknown address\n"); exit(1); } return addr; }
37
240-322 Cli/Serv.: sockets 3/937 Notes The client must ‘wake up’ the server by sending it a dummy message ( MSG ). The server uses the client address information included in the sendto() call to direct its answer. continued
38
240-322 Cli/Serv.: sockets 3/938 get_udp_serv_addr() is the same as get_tcp_serv_addr() (part 7, slide 100) except that the service type in getservbyname() is “udp”.
39
240-322 Cli/Serv.: sockets 3/939 Usage $./day_cus calvin /*on fivedots*/ Wed May 4 09:42:33 2005 $./day_cus fivedots Wed May 4 09:42:39 2005 The usual response is to get nothing back; day_cus hangs, waiting forever
40
240-322 Cli/Serv.: sockets 3/940 Timeouts in UDP v Have the code wait for a message for a certain amount of time, then timeout. v Three main approaches: –use the timeout feature of select(); –set an alarm which interrupts the waiting process after a certain amount of time; –configure the socket to timeout using (non- standard) socket options. continued
41
240-322 Cli/Serv.: sockets 3/941 v Details in: –UNIX Network Programming (Vol. 1: Networking APIs: Sockets and XTI) W. Richard Stevens
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.