300 likes | 386 Views
Example Servers Pt 1. Objective: To discuss key aspects of various server implementations. Server Example Outline. Support Functions passiveUDP ( ) passivesock ( ) Iterative - Connectionless ( UDPTimed.cpp ) Iterative - Connection-Oriented ( TCPdtd.cpp )
E N D
Example Servers Pt 1 Objective: To discuss key aspects of various server implementations
Server Example Outline • Support Functions • passiveUDP ( ) • passivesock ( ) • Iterative - Connectionless (UDPTimed.cpp) • Iterative - Connection-Oriented (TCPdtd.cpp) • Concurrent Connection-Oriented (TCPEchod.cpp) • Single Process Concurrent (TCPMechod.cpp)
Iterative Connectionless Servers (UDP) /* passUDP.cpp - passiveUDP */ #include <winsock.h> SOCKET passivesock(const char *, const char *, int); /*-------------------------------------------------- * Create a passive socket for use in a UDP server *------------------------------------------------*/ SOCKET passiveUDP(const char *service) { return passivesock(service, "udp", 0); }
passivesock (service, protocol, qlen) /* passsock.cpp - passivesock */ #include <stdlib.h> #include <string.h> #include <winsock.h> void errexit(const char *, ...); u_short portbase = 0; /* For test servers */ /*----------------------------------------------- * passivesock - allocate & bind a server socket using TCP or UDP *----------------------------------------------*/
passivesock (service, protocol, qlen) SOCKET passivesock(const char *service, const char *transport, int qlen) { struct servent *pse; // Service info entry struct protoent *ppe; // Protocol info entry struct sockaddr_in sin; // Internet address SOCKET s; // socket descriptor int type; //socket type (SOCK_STREAM,SOCK_DGRAM) memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY;
passivesock (service, protocol, qlen) SOCKET passivesock(const char *service, const char *transport, int qlen) { struct servent *pse; // Service info entry struct protoent *ppe; // Protocol info entry struct sockaddr_in sin; // Internet address SOCKET s; // socket descriptor int type; //socket type (SOCK_STREAM,SOCK_DGRAM) memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY;
passivesock (service, protocol, qlen) /* Map service name to port number */ if ( pse = getservbyname(service, transport) ) sin.sin_port = htons(ntohs((u_short)pse->s_port) + portbase); else if ((sin.sin_port = htons((u_short)atoi(service)))==0) errexit("can't get \"%s\" service \n", service); /* Map protocol name to protocol number */ if ( (ppe = getprotobyname(transport)) == 0) errexit("can't get \"%s\" protocol \n", transport); /* Use protocol to choose a socket type */ if (strcmp(transport, "udp") == 0) type = SOCK_DGRAM; else type = SOCK_STREAM;
passivesock (service, protocol, qlen) /* Allocate a socket */ s = socket(PF_INET, type, ppe->p_proto); if (s == INVALID_SOCKET) errexit(”Socket Error: %d\n", GetLastError()); /* Bind the socket */ if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == SOCKET_ERROR) errexit(”Bind Error: %s port: %d\n", service, GetLastError()); if (type==SOCK_STREAM && listen(s, qlen)== SOCKET_ERROR) errexit(”can’t listen on %s port: %d\n", service, GetLastError()); return s; }
passivesock (service, protocol, qlen) /* Allocate a socket */ s = socket(PF_INET, type, ppe->p_proto); if (s == INVALID_SOCKET) errexit(”Socket Error: %d\n", GetLastError()); /* Bind the socket */ if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == SOCKET_ERROR) errexit(”Bind Error: %s port: %d\n", service, GetLastError()); if (type==SOCK_STREAM && listen(s, qlen)== SOCKET_ERROR) errexit(”can’t listen on %s port: %d\n", service, GetLastError()); return s; }
Iterative Connectionless ServersTIME Server /* UDPtimed.cpp - main */ #include <time.h> #include <winsock.h> SOCKET passiveUDP(const char *); void errexit(const char *, ...); #define WINEPOCH 2208988800 // Windows epoch #define WSVERS MAKEWORD(2, 0) /*-------------------------------------------------- * main - Iterative UDP server for TIME service *------------------------------------------------ */
Iterative Connectionless ServersTIME Server int main(int argc, char *argv[]) { struct sockaddr_in fsin; // From address of client char *service = "time";// service name or port # char buf[2048];//"input" buffer; any size >1 packet SOCKET sock; // server socket time_t now; // current time int alen; // from-address length WSADATA wsadata;
Iterative Connectionless ServersTIME Server switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("usage: UDPtimed [port]\n"); } if (WSAStartup(WSVERS, &wsadata)) errexit("WSAStartup failed\n"); sock = passiveUDP(service);
Iterative Connectionless ServersTIME Server while (1) { alen = sizeof(fsin); if (recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&fsin, &alen) == SOCKET_ERROR) errexit("recvfrom: error %d\n",GetLastError()); (void) time(&now); now = htonl((u_long)(now + WINEPOCH)); (void) sendto(sock, (char *)&now, sizeof(now), 0, (struct sockaddr *)&fsin, sizeof(fsin)); } return 1; /* not reached */ }
Iterative Connectionless ServersTIME Server while (1) { alen = sizeof(fsin); if (recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&fsin, &alen) == SOCKET_ERROR) errexit("recvfrom: error %d\n",GetLastError()); (void) time(&now); now = htonl((u_long)(now + WINEPOCH)); (void) sendto(sock, (char *)&now, sizeof(now), 0, (struct sockaddr *)&fsin, sizeof(fsin)); } return 1; /* not reached */ }
Iterative Connection OrientedTCPdaytimed /* TCPdtd.cpp - main, TCPdaytimed */ #include <stdlib.h> #include <winsock.h> #include <time.h> void errexit(const char *, ...); void TCPdaytimed(SOCKET); SOCKET passiveTCP(const char *, int); #define QLEN 5 #define WSVERS MAKEWORD(2, 0) /*------------------------------------------------- * main - Iterative TCP server for DAYTIME service *------------------------------------------------ */
Iterative Connection OrientedTCPdaytimed void main(int argc, char *argv[]){ struct sockaddr_in fsin; //From address of client char *service = "daytime"; //Service or port # SOCKET msock, ssock; // master & slave sockets int alen; // from-address length WSADATA wsadata; switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("usage: TCPdaytimed [port]\n"); }
Iterative Connection OrientedTCPdaytimed if (WSAStartup(WSVERS, &wsadata) != 0) errexit("WSAStartup failed\n"); msock = passiveTCP(service, QLEN); while (1) { alen = sizeof(struct sockaddr); ssock = accept(msock,(struct sockaddr*)&fsin, &alen); if (ssock == INVALID_SOCKET) errexit("accept failed: %d\n", GetLastError()); TCPdaytimed(ssock); (void) closesocket(ssock); } }
Iterative Connection OrientedTCPdaytimed void TCPdaytimed(SOCKET fd) { char *pts; // pointer to time string time_t now; // current time (void) time(&now); pts = ctime(&now); (void) send(fd, pts, strlen(pts), 0); }
Concurrent Connection-OrientedTCPechod.c /* TCPechod.cpp - main, TCPechod */ #include <stdio.h>, <winsock.h>, <process.h> #define QLEN 5 // max connection queue length #define STKSIZE 16536 #define BUFSIZE 4096 #define WSVERS MAKEWORD(2, 0) SOCKET msock, ssock; // master & slave sockets int TCPechod(SOCKET); void errexit(const char *, ...); SOCKET passiveTCP(const char *, int);
Concurrent Connection-OrientedTCPechod.c int main(int argc, char *argv[]) { char *service = "echo";// service name, port # struct sockaddr_in fsin; // address of a client int alen; // length of client's address WSADATA wsadata; switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("usage: TCPechod [port]\n"); } if (WSAStartup(WSVERS, &wsadata) != 0) errexit("WSAStartup failed\n");
Concurrent Connection-OrientedTCPechod.c msock = passiveTCP(service, QLEN); while (1) { alen = sizeof(fsin); ssock = accept(msock, (struct sockaddr *)&fsin, &alen); if (ssock == INVALID_SOCKET) errexit("accept error %d\n", GetLastError()); if (_beginthread((void (*)(void *))TCPechod, STKSIZE, (void *)ssock) < 0) errexit("_beginthread: %s\n", strerror(errno)); } return 1; /* not reached */ }
Concurrent Connection-OrientedTCPechod.c intTCPechod(SOCKET fd){ char buf[BUFSIZE]; int cc; cc =recv(fd, buf, sizeofbuf, 0); while (cc != SOCKET_ERROR && cc > 0) { if (send(fd, buf, cc, 0) == SOCKET_ERROR) { printf("send error: %d\n", GetLastError()); break; } cc = recv(fd, buf, sizeofbuf, 0); } if (cc == SOCKET_ERROR) printf("recv error: %d\n", GetLastError()); closesocket(fd); return 0; }
Managing multiple sockets Start Create Master Socket
Managing multiple sockets First Client Connection Second Client Connection
Single-Process ConcurrentTCPmechod.c void main(int argc, char *argv[]){ char *service = "echo";// service name/port # struct sockaddr_in fsin; // From address of client SOCKET msock; // master server socket fd_set rfds; // read file descriptor set fd_set afds; // active file descriptor set int alen; // from-address length WSADATA wsdata; unsigned int fdndx; switch (argc) { case 1: break; case 2: service = argv[1]; break; default: errexit("usage: TCPmechod [port]\n"); }
Single-Process ConcurrentTCPmechod.c if (WSAStartup(WSVERS, &wsdata) != 0) errexit("WSAStartup failed\n"); msock = passiveTCP(service, QLEN); FD_ZERO(&afds); FD_SET(msock, &afds); 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());
Single-Process ConcurrentTCPmechod.c if (WSAStartup(WSVERS, &wsdata) != 0) errexit("WSAStartup failed\n"); msock = passiveTCP(service, QLEN); FD_ZERO(&afds); FD_SET(msock, &afds); 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());
Single-Process ConcurrentTCPmechod.c if (WSAStartup(WSVERS, &wsdata) != 0) errexit("WSAStartup failed\n"); msock = passiveTCP(service, QLEN); FD_ZERO(&afds); FD_SET(msock, &afds); 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());
Single-Process ConcurrentTCPmechod.c if (FD_ISSET(msock, &rfds)) { SOCKET ssock; alen = sizeof(fsin); ssock = accept(msock,(structsockaddr *)&fsin,&alen); if (ssock == INVALID_SOCKET) errexit("accept: error %d\n", GetLastError()); FD_SET(ssock, &afds); } for (fdndx=0; fdndx<rfds.fd_count; ++fdndx){ SOCKET fd = rfds.fd_array[fdndx]; if (fd != msock && FD_ISSET(fd, &rfds)) if (echo(fd) == 0) { (void) closesocket(fd); FD_CLR(fd, &afds); } } } }
Single-Process ConcurrentTCPmechod.c // echo - echo one buffer of data, returning byte count int echo(SOCKET fd) { char buf[BUFSIZE]; int cc; cc = recv(fd, buf, sizeof buf, 0); if (cc == SOCKET_ERROR) errexit("echo recv error %d\n", GetLastError()); if (cc && send(fd, buf, cc, 0) == SOCKET_ERROR) errexit("echo send error %d\n", GetLastError()); return cc; }