150 likes | 281 Views
Example Servers Pt 2. Objective: To discuss key aspects of various server implementations. Server Example Outline. Multi-Protocol Server ( Daytimed.cpp ) Multi-Service Server ( Superd.c ). Multiprotocol Server daytimed.c. /* daytimed.cpp - main, daytime */ #include <stdio.h>
E N D
Example Servers Pt 2 Objective: To discuss key aspects of various server implementations
Server Example Outline • Multi-Protocol Server • (Daytimed.cpp) • Multi-Service Server • (Superd.c)
Multiprotocol Server daytimed.c /* daytimed.cpp - main, daytime */ #include <stdio.h> #include <time.h> #include <winsock.h> void daytime(char buf[]); void errexit(const char *, ...); SOCKET passiveTCP(const char *, int); SOCKET passiveUDP(const char *); #define WSVERS MAKEWORD(2, 0) #define QLEN 5 #define LINELEN 128
Multiprotocol Server daytimed.c void main(int argc, char *argv[]) { char *service = "daytime";// service name char buf[LINELEN+1]; // line buffer struct sockaddr_in fsin; // Request from address int alen; // from-address length SOCKET tsock; // TCP master socket SOCKET usock; // UDP socket fd_set rfds; // readable file descriptors int rv; WSADATA wsadata;
Multiprotocol Server daytimed.c switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("usage: daytimed [port]\n"); } if (WSAStartup(WSVERS, &wsadata) != 0) errexit("WSAStartup failed\n"); tsock = passiveTCP(service, QLEN); usock = passiveUDP(service); FD_ZERO(&rfds);
Multiprotocol Server daytimed.c while (1) { FD_SET(tsock, &rfds); FD_SET(usock, &rfds); if(select(FD_SETSIZE,&rfds,(fd_set*)0,(fd_set*)0, (structtimeval *)0) == SOCKET_ERROR) errexit("select error: %d\n", GetLastError()); if (FD_ISSET(tsock, &rfds)) { SOCKET ssock; /* TCP slave socket */ alen = sizeof(fsin); ssock = accept(tsock, (structsockaddr *)&fsin, &alen); if (ssock == INVALID_SOCKET) errexit("accept failed: %d\n",GetLastError());
Multiprotocol Server daytimed.c daytime(buf); (void) send(ssock, buf, strlen(buf), 0); (void) closesocket(ssock); } if (FD_ISSET(usock, &rfds)) { alen = sizeof(fsin); rv = recvfrom(usock, buf, sizeof(buf), 0, (structsockaddr *)&fsin, &alen); if (rv == SOCKET_ERROR) errexit("recvfrom: error %d\n",GetLastError()); daytime(buf); (void) sendto(usock, buf, strlen(buf), 0, (structsockaddr *)&fsin, sizeof(fsin)); } } }
Multiprotocol Server daytimed.c /*----------------------------------------------------- * daytime - fill the given buffer with the time of day *-----------------------------------------------------*/ void daytime(char buf[]) { time_t now; (void) time(&now); sprintf(buf, "%s", ctime(&now)); }
Multi-service Server - superd.c /* superd.cpp - main, doTCP */ #include <process.h> #include <winsock.h> #define UDP_SERV 0 #define TCP_SERV 1 struct service { char *sv_name; char sv_useTCP; SOCKET sv_sock; void (*sv_func)(SOCKET); }; void TCPechod(SOCKET), TCPchargend(SOCKET), TCPdaytimed(SOCKET), TCPtimed(SOCKET);
Multi-service Server - superd.c SOCKET passiveTCP(const char *, int); SOCKET passiveUDP(const char *); void errexit(const char *, ...); void doTCP(struct service *); struct service svent[] = { { "echo", TCP_SERV, INVALID_SOCKET, TCPechod }, { "chargen", TCP_SERV, INVALID_SOCKET, TCPchargend }, { "daytime", TCP_SERV, INVALID_SOCKET, TCPdaytimed }, { "time", TCP_SERV, INVALID_SOCKET, TCPtimed }, { 0, 0, 0, 0 }, }; #define WSVERS MAKEWORD(2, 0) #define QLEN 5 #define LINELEN 128 extern u_shortportbase; /* from passivesock() */
Multi-service Server - superd.c void main(int argc, char *argv[]) { struct service *psv; // service table pointer fd_set afds, rfds; /* file descriptors WSADATA wsdata; switch (argc) { case 1: break; case 2: portbase = (u_short) atoi(argv[1]); break; default: errexit("usage: superd [portbase]\n"); } if (WSAStartup(WSVERS, &wsdata)) errexit("WSAStartup failed\n"); FD_ZERO(&afds);
Multi-service Server - superd.c for (psv = &svent[0];psv->sv_name; ++psv) { if (psv->sv_useTCP) psv->sv_sock = passiveTCP(psv->sv_name, QLEN); else psv->sv_sock = passiveUDP(psv->sv_name); FD_SET(psv->sv_sock, &afds); }
Multi-service Server - superd.c while (1) { memcpy(&rfds, &afds, sizeof(rfds)); if (select(FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0,(struct timeval *)0) == SOCKET_ERROR) errexit("select error: %d\n", GetLastError()); for (psv=&svent[0]; psv->sv_name; ++psv) { if (FD_ISSET(psv->sv_sock, &rfds)) { if (psv->sv_useTCP) doTCP(psv); else psv->sv_func(psv->sv_sock); } } }
Multi-service Serversuperd.c /*---------------------------------------------------- * doTCP - handle a TCP service connection request *--------------------------------------------------*/ void doTCP(struct service *psv){ struct sockaddr_in fsin; // Request from address int alen; /* from-address length */ SOCKET ssock; alen = sizeof(fsin); ssock = accept(psv->sv_sock,(struct sockaddr*)&fsin,&alen); if (ssock == INVALID_SOCKET) errexit("accept: %d\n", GetLastError()); if (_beginthread((void (*)(void *))psv->sv_func, 0, (void *)ssock) == (unsigned long) -1) errexit("_beginthread: %s\n", strerror(errno)); }
Summary • Servers can use different concurrency techniques to support multiple services at the same time. • Multiprotocol servers support a single server, but through multiple protocols • Multiservice servers share a common infrastructure (process context, etc.) across a number of small, low utilization servers to improve the efficiency of service support.