150 likes | 259 Views
This document provides an in-depth discussion of various multi-protocol server implementations, delving into essential components, including multi-service configurations and specific code examples. The focus is on two primary server examples: the multi-protocol Daytimed server and the multi-service Superd server. These implementations highlight various techniques for managing TCP and UDP protocols, including functions for accepting connections, handling data transfer, and sending time data. This resource is designed for those looking to enhance their understanding of server architecture and network communication protocols.
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.