1 / 68

TDC561 Network Programming

Explore various designs like Concurrent, Iterative, and Statelessness in client/server applications. Learn about server concurrency strategies like One Child per Client and pre-threaded servers. Dive into code examples and practical implementations.

sayles
Download Presentation

TDC561 Network Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. TDC561 Network Programming Week 4: • Client/Server Design Approaches • Case Study Using Sockets – • A Client Server Application of Network Performance Management • presentation prepared with the help of • Dale Knudson PhD, Lucent Technologies

  2. Douglas Comer, David Stevens, Internetworking with TCP/IP : Client-Server Programming, Volume III (BSD Unix and ANSI C), 2nd edition, 1996 (ISBN 0-13-260969-X) Chap. 2, 8 W. Richard Stevens, Network Programming : Networking API: Sockets and XTI, Volume 1, 2nd edition, 1998 (ISBN 0-13-490012-X) Chap. 7 (partial), 27 (partial), 16.1-16.3 (partial) References

  3. Server Design Iterative Connectionless Iterative Connection-Oriented Concurrent Connectionless Concurrent Connection-Oriented

  4. Concurrent vs. Iterative • Concurrent • Large or variable size requests • Harder to program • Typically uses more system resources • Iterative • Small, fixed size requests • Easy to program

  5. Connectionless vs. Connection-Oriented • Connection-Oriented • Easy to program • Transport protocol handles the tough stuff. • Requires separate socket for each connection. • Connectionless • Less overhead • No limitation on number of clients

  6. Statelessness • State: Information that a server maintains about the status of ongoing client interactions. • Issues with Statefullness • Clients can go down at any time. • Client hosts can reboot many times. • The network can lose messages. • The network can duplicate messages. • Example • Connectionless servers that keep state information must be designed carefully • Messages can be duplicated

  7. Concurrent Server Design Alternatives • One child per client • Single Process Concurrency (AKA Pseudo-Concurrency or Apparent Concurrency) • Pre-forking multiple processes • Spawn one thread per client • Pre-threaded Server will be discussed in a future lecture

  8. One child per client • Traditional Unix server: • TCP: after call to accept(), call fork(). • UDP: after recvfrom(), call fork(). • Each process needs only a few sockets. • Small requests can be serviced in a small amount of time. • Parent process needs to clean up after children (call wait() ).

  9. Discussion Stevens Example: Concurrency using fork() 1/3 /* Code fragment that uses fork() and signal() to implement concurrency */ /* include and define statements section */ void signal_handler(int sig) { int status; wait(&status); /* awaits child process to exit therefore allows child to terminate, and to transit from ZOMBIE to NORMAL TEMINATION (END) state */ signal(SIGCHLD,&signal_handler); /* restarts signal handler */ }

  10. Discussion Stevens Example: Concurrency using fork() 2/3 main(int argc, char *argv[]) { /* Variable declaration section */ /* The calls socket(), bind(), and listen() */ signal(SIGCHLD,&signal_handler); while(1) { /* infinite accept() loop */ newfd = accept(sockfd,(struct sockaddr *)&theiraddr,&sinsize); if (newfd < 0) { /* error in accept() */ if (errno = EINTR) continue; else { perror("accept"); exit(-1); } } See previous slide

  11. Discussion Stevens Example: Concurrency using fork() 3/3 /* successfully accepted a new client connection newfd >=0 */ switch (fork()) { case -1: /* fork() error */ perror("fork"); exit(-1); case 0: /* child handles request */ close(sockfd); /* read msg and form a response */ /* send response back to the client */ close(newfd); exit(-1); /* exit() sends by default SIGCHLD to parent */ default: /* parent returns to wait for another request */ close(newfd); } /* end switch */ } /* end while(1) */ }

  12. Discussion: Single Process Concurrency 1/2 main(int argc, char *argv[]) { /* various declarations */ int result; fd_set readfds, testfds; /* socket(), bind(), listen() … */ /* inititialization of the fd set FD_ZERO(&readfds); /* add listening socket sockfd to the reading set */ FD_SET(sockfd,&readfds); while(1) { int fd; testfds = readfds; result = select(FD_SETSIZE, &testfds, NULL, NULL, NULL); /* error check for select */

  13. Discussion: Single Process Concurrency 2/2 for (fd = 0; fd < FD_SETSIZE; fd++) { if (FD_ISSET(fd,&testfds)) { /* find activated socket fd */ if (fd == sockfd) { /* ==> New connection */ newfd = accept(sockfd,(struct sockaddr *)&theiraddr,&sinsize); FD_SET(newfd,&readfds); /* update file descriptor set with newfd */ } else { /* ==> request from ``old'' connection */ /* call read() and handle request from old connection using fd */ close(fd); FD_CLR(fd,&readfds); /* remove fd when connection finished */ } /* else */ } /* end if (FD_ISSET() */ } / * end for (; ; ) */ } /* end while(1) */ return 1; }

  14. OAM&P - Operations, Administration, Maintenance and Provisioning • ITU Categories • (International Telecommunications Union) • Configuration Management (CM) • Accounting Management (AM) • Fault Management (FM) • Performance Management (PM) • Security Management (SM)

  15. Performance Management Custom Reports PM report (one per hour) OSS NM Wireless Switch ftp What if you want the data more frequently? OSS NM – Operation Support System - Network Manager

  16. Every 5 minutes (but how much data?) OMP Server Collection Specification Part A – every 1 hour Part B – every 30 minutes Part C – every 5 minutes OMP OMP Server (Operations and Maintenance Platform Server)

  17. OMP Master Clock PM Poll for data PM PM PM

  18. OMP Web browser Ethernet

  19. OMP Web Server Web browser Ethernet

  20. OMP Web Server HTML pages Web browser Ethernet

  21. OMP Web Server Generated HTML HTML pages CGI Script Web browser PM hourly data Ethernet

  22. OMP Web Server Generated HTML HTML pages CGI Script Web browser PM hourly data PM On Demand data Ethernet

  23. OMP Web Server Generated HTML HTML pages CGI Script On Demand data Web browser PM hourly data PM Hourly Collection PM On Demand Collection Ethernet

  24. OMP Web Server Generated HTML HTML pages Web Browser Java applet CGI Script PM hourly data On Demand data User Terminal PM Hourly Collection PM On Demand Collection Ethernet

  25. OMP Web Server Generated HTML HTML pages Web Browser Java applet Client CGI Script PM hourly data On Demand data User Terminal Socket PM Hourly Collection PM On Demand Collection Server Ethernet

  26. CREATE A SERVER SOCKET AF_INET = use TCP/IP internet protocols SOCK_STREAM = connection oriented socket (not datagrams) s_sock = socket( AF_INET, SOCK_STREAM, 0) Note that this socket is not yet associated with a port number. On Demand Collection (server socket)

  27. CREATE A SERVER SOCKET s_sock = socket( AF_INET, SOCK_STREAM,0) bind will associate s_sock with a local name or address/port pair. memset(&serv_adr, 0, sizeof(serv_adr)); serv_adr.sin_family = AF_INET; serv_adr.sin_addr.s_addr = INADDR_ANY; serv_adr.sin_port = htons(PORT); bind (s_sock, (struct sockaddr *)(&serv_adr), sizeof(serv_adr)); Note that this port number will be known to all the clients. On Demand Collection (server socket)

  28. CREATE A SERVER SOCKET s_sock = socket( AF_INET, SOCK_STREAM,0) bind (s_sock, (struct sockaddr *)(&serv_adr), sizeof(serv_adr)); Set up a queue for incoming connection requests. In this case set up for a maximum of 5 clients. listen (s_sock, 5); On Demand Collection (server socket)

  29. CREATE A CLIENT SOCKET AF_INET = use TCP/IP internet protocols SOCK_STREAM = connection oriented socket (not datagrams) c_sock = socket( AF_INET, SOCK_STREAM, 0) Note that this socket is not yet associated with a local or destination address. Java applet (socket client)

  30. CREATE A CLIENT SOCKET c_sock = socket( AF_INET, SOCK_STREAM,0); Connect binds a permanent destination to a socket, placing it in the connected state. Internet address interpretation routine – translates from dotted decimal format (e.g., a.b.c.d) to a 32 bit internet address. serv_adr.sin_family = AF_INET; serv_adr.sin_addr.s_addr = inet_addr(serv_address); serv_adr.sin_port = htons(PORT); connect (c_sock, (*sockaddr *)&server, sizeof(server)); Java applet (socket client)

  31. CREATE A CLIENT SOCKET c_sock = socket( AF_INET, SOCK_STREAM,0); connect (c_sock, (*sockaddr *)&server, sizeof(server)); The client can now start reading and writing on the socket. Do { buf = message to send to the server write (c_sock, buf, len); read (c_sock, buf, len); process response message received from the server } while (1); /* or until complete */ Java applet (socket client)

  32. Known port number On Demand Collection (socket server) Java applet (socket client)

  33. CREATE A SERVER SOCKET s_sock = socket( AF_INET, SOCK_STREAM,0) bind (s_sock, (struct sockaddr *)(&serv_adr), sizeof(serv_adr)); listen (s_sock, 5); Once a socket has been set up, the server needs to wait for a connection. To do so, it uses system call accept. A call to accept blocks until a connection request arrives. do { new_sock = accept (s_sock, (struct sockaddr *) &client_adr, &client_len); if (fork() == 0) { /* in CHILD process */ while ((len=read(new_sock, buf, size)){ /* process message */ } close (new_sock); exit(0); } else close (new_sock); /* in parent */ } while (1); /* process messages forever */ On Demand Collection (server socket)

  34. CREATE A SERVER SOCKET s_sock = socket( AF_INET, SOCK_STREAM,0) bind (s_sock, (struct sockaddr *)(&serv_adr), sizeof(serv_adr)); listen (s_sock, 5); new_sock = accept (s_sock, (struct sockaddr *) &client_adr, &client_len); When a request arrives, the system fills in client_adr with the address of the client that placed the request. The system creates a new socket file descriptor, new_sock, that has its destination connected to the requesting client. On Demand Collection (server socket)

  35. Known port Number Listening/ Passive socket On Demand Collection (socket server) Java applet (socket client) Active socket (returned by accept) When the server accepts a connection from a client, a new file descriptor is assigned.

  36. Second Client Known port number On Demand Collection (socket server) Java applet (socket client)

  37. Question: How can we have a single process handle all the client interfaces and at the same time do all PM count retrieval from the cells? Why would we want to do this?

  38. void ODinit() { /* Call the signal handler if we get one a SIGPOLL signal. This indicates that ** a socket needs servicing. */ (void) sigset (SIGPOLL, odsig_handler); --- continued later --- } static void ODsig_handler (int sig) { switch (sig) { case SIGPOLL: sigpoll_flag = TRUE; default: break; } }

  39. main ( ) { /* On Demand collection process */ ODinit(); /* initialize the socket * while (1) { while (ODwork_to_do()){ ODdo_work(); } ODwait_for_work(); } }

  40. Void ODwait_for_work ( void ) /* Define how to react to Asynchronous Events - messages */ { uxretval = UXWGETMSG ( &uxmbuf, UXFOREVER ); switch ( uxretval) { case UXMSG: /* Process the UXMSG received from a cell - Network Element */ ODuxmsg(&uxmbuf ); break; case UXEINTR: /* Got an interrupt. Handled on return from this function */ break; case UXENOPORT: /* Somehow the port we are doing the UXWGETMSG on got dropped */ /* Restart the Unix port */ uxretval = UXCONNPORT(ITPT_OD); break; default: break; } }

  41. int ODwork_to_do (void) { if (cl1timerflag || cl2timerflag || … ) return (TRUE); if (rsp1timerflag || rsp2timerflag || … ) return (TRUE); if (sigpoll_flag) return (TRUE); return (FALSE); }

  42. Void ODdo_work ( void ) { if (sigpoll_flag) { /* Process client request */ sigpoll_flag = FALSE; ODclient_req();  remember this one } if (cl1timerflag) { /* Process periodic request to Network elements (cells, ..)*/ ODmsgdest (ODCL1TIMERTAG); odcl1timerflag = FALSE; } if (rsp1timerflag) { /* Timed out waiting for response from Network elements (cells, ..)*/ ODerr(ODRSP1TIMERTAG); ODRSP1TIMERTAG = FALSE; } if (audit_timer_flag) { /* Time for a socket audit */ ODsock_audit(); } }

  43. ODinit continued Void ODinit () { /* Initialize the server structure */ server.sin_addr.s_addr = INADDR_ANY; server.sin_family = AF_INET; /* Get the service port associated with this process usually in some /etc/ config file such as /etc/services */ servent_p = getservbyname ( PMSERVICE, “tcp” ); /* NOTE: API is not IPv6 compliant!*/ server.sin_port = servent_p->s_port; /* Now create the connection socket */ ODsock =socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); /* Allow local address reuse */ on = 1; setsockopt (ODsock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));

  44. ODinit continued Void ODinit () { /* Bind the socket to the local address specified on the server. This establishes a local address for the socket. */ bind (ODsock, (struct sockaddr *) (&server), sizeof(server)); /* Set up the server to listen for connection requests from the client. This simply marks the socket as ready to receive a connection. It does not wait for the client to connect. */ (void) listen (ODsock, 10); /* allow 10 connections pending */

More Related