270 likes | 418 Views
Example Client Program. Reference Comer & Stevens, Chapter 7. Example Windows Client. Develop a set of procedures that can be used by other programs to implement client / server. int connectUDP (host, service) int connectsock(host, service, “udp”) [identify service, host, port]
E N D
Example Client Program Reference Comer & Stevens, Chapter 7
Example Windows Client • Develop a set of procedures that can be used by other programs to implement client / server. int connectUDP (host, service) int connectsock(host, service, “udp”) [identify service, host, port] [get a socket] [connect to service / host / port] [return socket number]
Example Windows ClientconnectTCP.c #include <winsock.h> SOCKET connectTCP (char *host, char *service) { return connectsock (host, service, “tcp”); } SOCKET connectUDP (char *host, char *service) { return connectsock (host, service, “udp”); }
Example Windows Clientconnectsock.c #include <stdlib.h>, <stdio.h>, <string.h>,<winsock.h> SOCKET connectsock (char *host, char *service, char *transport) { struct hostent *phe; struct servent *pse; struct protoent *ppe; struct sockaddr_in sin; int s, type;
Example Windows Clientconnectsock.c memset(&sin, 0, sizeof (sin)); sin.sin_family = AF_INET; if (pse = getservbyname (service, transport) ) sin.sin_port = pse ->s_port; else if ( (sin.sin_port = htons((u_short)atoi(service))) == 0) errexit (“can’t get %s service\n”, service); if (phe = gethostbyname (host) ) memcpy(&sin.sin_addr, phe->h_addr, phe->h_length); else if ((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) errexit (“can’t get %s host\n”, host);
Example Windows Clientconnectsock.c if ( (ppe = getprotobyname (transport) == 0) errexit (“can’t get %s protocol entry\n”,transport); if (strcmp (transport, “tcp”) == 0) type = SOCK_STREAM; else type = SOCK_DGRAM; if( (s = socket (PF_INET, type, ppe->p_proto)) == INVALID_SOCKET) errexit (“Can’t create a socket: %d\n”, GetLastError()); if (connect (s, (struct sockaddr *)&sin, sizeof(sin)) == SOCKET_ERROR) errexit (“can’t connect to remote socket\n”); return s; }
Example client program • Echo client (connection-oriented) Establish a connection to server while (user enters text) send text to server receive text back from server display received message on screen close connection & exit
tcpecho ( ) #include <stdlib.h>,<stdio.h>,<string.h>,<winsock.h> void TCPecho(const char *, const char *); void errexit(const char *, ...); SOCKET connectTCP(const char *, const char *); #define LINELEN 128 #define WSVERS MAKEWORD(2, 0) void main(int argc, char *argv[]) { char *host = "localhost"; /* host to use if none supplied */ char *service = "echo"; /* default service name */ : WSADATA wsadata; if (WSAStartup(WSVERS, &wsadata) != 0) errexit("WSAStartup failed\n"); TCPecho(host, service); WSACleanup(); exit(0); }
tcpecho ( ) – argument Switch #include <stdlib.h>,<stdio.h>,<string.h>,<winsock.h> void TCPecho(), errexit(), connectTCP(); #define LINELEN 128, WSVERS MAKEWORD(2, 0) void main(int argc, char *argv[]) { char *host = "localhost"; /* host to use if none supplied */ char *service = "echo"; /* default service name */ switch (argc) { case 1: break; case 3: service = argv[2]; //Fall Through!! case 2: host = argv[1]; break; default; printf (“Usage: %s [host[port]]\n”, argv[0]); exit(1); } WSADATA wsadata; if (WSAStartup(WSVERS, &wsadata) != 0) errexit("WSAStartup failed\n"); TCPecho(host, service); WSACleanup(); exit(0);
tcpecho (cont) void TCPecho(const char *host, const char *service) { char buf[LINELEN+1]; /* buffer for one line of text */ SOCKET s; /* socket descriptor */ int cc, outchars, inchars; /* characters counts */ s = connectTCP(host, service); while (fgets(buf, sizeof(buf), stdin)) { buf[LINELEN] = '\0'; /* ensure line null-termination */ outchars = strlen(buf); (void) send(s, buf, outchars, 0); for (inchars = 0; inchars < outchars; inchars += cc) { cc = recv(s, &buf[inchars], outchars-inchars, 0); if (cc == SOCKET_ERROR) errexit("socket recv failed: %d\n", GetLastError()); }fputs(buf, stdout); } closesocket(s); }
UDPecho.cpp #include <stdlib.h>, <stdio.h>, <string.h>, <winsock.h> void UDPecho(const char *, const char *); void errexit(const char *, ...); SOCKET connectUDP(const char *, const char *); #define LINELEN 128 #define WSVERS MAKEWORD(2, 0) void main(int argc, char *argv[]) { char *host = "localhost", *service = "echo"; WSADATA wsadata; if (WSAStartup(WSVERS, &wsadata)) errexit("WSAStartup failed\n"); UDPecho(host, service); WSACleanup(); exit(0); }
UDPecho.cpp void UDPecho(const char *host, const char *service) { char buf[LINELEN+1];/* buffer for one line of text */ SOCKET s; /* socket descriptor */ int nchars; /* read count*/ s = connectUDP(host, service); while (fgets(buf, sizeof(buf), stdin)) { buf[LINELEN] = '\0'; /* ensure null-terminated */ nchars = strlen(buf); (void) send(s, buf, nchars, 0); if (recv(s, buf, nchars, 0) < 0) errexit("recv failed: error %d\n", GetLastError()); fputs(buf, stdout); } }
UDPecho_cnls.cpp #include <stdlib.h>,<stdio.h>,<string.h>,<winsock.h> ….. // function prototypes, defines, etc. void main(int argc, char *argv[]) { char *host = "localhost", *service = "echo"; WSADATA wsadata; switch (argc) {… } // test for command line params if (WSAStartup(WSVERS, &wsadata)) errexit("WSAStartup failed\n"); UDPecho_cnls(host, service); WSACleanup(); exit(0); }
UDPecho_cnls.cpp (cont) void UDPecho_cnls(const char *host, const char *service) { char buf[LINELEN+1];/*buffer for text */ SOCKET s; /* socket descriptor */ int nchars; /* read count*/ struct hostent *phe; /* * host info entry */ struct servent *pse; /* * service info entry */ struct protoent *ppe; /* * protocol info entry */ struct sockaddr_in sin; /* Internet endpoint addr*/ int type, status; /* socket descriptor & type*/ char *transport = "udp";/*Transport service name*/
UDPecho_cnls.cpp (cont) memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; /* Map service name to port number */ if ( pse = getservbyname(service, transport) ) sin.sin_port = pse->s_port; else if ( (sin.sin_port = htons((u_short)atoi(service)))== 0) errexit("can't get \"%s\" service entry\n", service); /*Map host name to IP address, dotted decimal(?)*/ if ( phe = gethostbyname(host) ) memcpy(&sin.sin_addr,phe->h_addr,phe->h_length);
UDPecho_cnls.cpp (cont) else if( (sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) errexit("can't get \"%s\" host entry\n", host); printf("Server at %s\n",inet_ntoa(sin.sin_addr)); /* Map protocol name to protocol number */ if ( (ppe = getprotobyname(transport)) == 0) errexit("Can't get \"%s\" entry\n", transport); /* Use protocol to choose a socket type */ if (strcmp(transport, "udp") == 0) type = SOCK_DGRAM; else type = SOCK_STREAM;
UDPecho_cnls.cpp (cont) /* Allocate a socket */ s = socket(PF_INET, type, ppe->p_proto); if (s == INVALID_SOCKET) errexit("Socket error: %d\n", GetLastError()); printf("Enter data to send...\n"); while (fgets(buf, sizeof(buf), stdin)) { buf[LINELEN] = '\0';/* ensure null-terminated */ nchars = strlen(buf); status = sendto(s, buf, nchars, 0, (struct sockaddr FAR *)&sin,sizeof(sin)); if (status == SOCKET_ERROR) errexit("Sendto failed: %d\n", GetLastError());
UDPecho_cnls.cpp (cont) printf ("We just sent a datagram\n"); if (recvfrom(s,buf,LINELEN,0,NULL,NULL) < 0) errexit("recv failed: %d\n",GetLastError()); printf("We got back %d characters: ", nchars); fputs(buf, stdout); } /* end of while */ }/* end of UDPecho () */
UDPecho_cnls.cpp – v2 #include <iostream> #include <stdlib.h> #include <string.h> #include <winsock.h> using namespace std; void UDPecho(const char *, const char *); #define LINELEN 128 #define WSVERS MAKEWORD(2, 0) #define ARGSIZE 25 int main(int argc, char *argv[]) { char host[ARGSIZE] = "localhost"; char service[ARGSIZE] = "12345"; WSADATA wsadata;
UDPecho_cnls.cpp – v2 switch (argc) { case 1: break; case 3: if (strlen(argv[2]) < ARGSIZE-1) strcpy_s (service,strlen(argv[2])+1 ,argv[2]); else { cout << "Service name too long!!" << endl; exit (1); } /* FALL THROUGH */ case 2: if (strlen(argv[1]) < ARGSIZE-1) strcpy_s (host,strlen(argv[1])+1 ,argv[1]); else { cout << "Service name too long!!" << endl; exit (1); } break;
UDPecho_cnls.cpp – v2 default: cout << "Usage: UDPecho [host [port]]\n" << endl; exit(1); } if (WSAStartup(WSVERS, &wsadata)) { cout << "WSAStartup failed" << endl; exit(1); } UDPecho(host, service); WSACleanup(); return 0; }
UDPecho_cnls.cpp – v2 void UDPecho(const char *host, const char *service) { char buf[LINELEN+1]; /* buffer for one line of text */ SOCKET s; /* socket descriptor */ int nchars; /* read count*/ struct hostent *phe; /* pointer to host information entry */ struct servent *pse; /* pointer to service information entry */ struct protoent *ppe; /* pointer to protocol information entry */ struct sockaddr_in sin; /* an Internet endpoint address */ int type, status; /* socket descriptor and socket type */ char *transport = "udp"; /* transport service name for port */ memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET;
UDPecho_cnls.cpp – v2 /* Map service name to port number */ if ( pse = getservbyname(service, transport) ) sin.sin_port = pse->s_port; else if ( (sin.sin_port = htons((u_short)atoi(service)))== 0) { cout << "Can't get \"" << service << "\" service entry" << endl; exit(1); } /* Map host name to IP address, allowing for dotted decimal */ if ( phe = gethostbyname(host) ) memcpy(&sin.sin_addr, phe->h_addr, phe->h_length); else if ( (sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) { cout << "Can't get \"" << host << "\" IP address "<< endl; exit(1); }
UDPecho_cnls.cpp – v2 cout <<"Our target server is at address " << inet_ntoa(sin.sin_addr) << endl; /* Map protocol name to protocol number */ if ( (ppe = getprotobyname(transport)) == 0) { cout << "Can't get \"" << transport << "\" protocol entry "<< endl; exit(1); } /* Socket type is UDP*/ type = SOCK_DGRAM; /* Allocate a socket */ s = socket(PF_INET, type, ppe->p_proto); if (s == INVALID_SOCKET) { cout << "Can't create socket" << endl; exit(1); }
UDPecho_cnls.cpp – v2 /* begin the data input / output loop... */ cout << "Enter data to send..." << endl; while (cin.getline(buf,LINELEN)) { buf[LINELEN] = '\0'; /* ensure null-terminated */ nchars = strlen(buf); status = sendto(s, buf, nchars, 0, (struct sockaddr FAR *)&sin, sizeof(sin)); if (status == SOCKET_ERROR) { cout << "Sendto failed ...: error " << GetLastError() << endl; exit(1); } cout << "We just sent a datagram" << endl;
UDPecho_cnls.cpp – v2 if (recvfrom(s, buf, LINELEN, 0, NULL, NULL) < 0) { cout << "recv failed: error" << GetLastError() << endl; exit(1); } if (strncmp(buf, "_quit", 5) == 0) { cout << "Goodbye......" << endl; break; } cout << "We got back the following " << nchars << " characters: " << endl; cout << buf << endl; } /* end of while */ }/* end of UDPecho () */
Sample Output C: \udpecho_cnls\Debug>udpecho_cnls lab222c Our target server is at address 134.193.2.253 Enter data to send... This is my data We just sent a datagram We got back the following 16 characters: This is my data This is another message We just sent a datagram We got back the following 24 characters: This is another message ^Z C: \udpecho_cnls\Debug>