cs423-cotter1 example client program reference comer & stevens, chapter 7

27
cs423-cotter 1 Example Client Program Reference Comer & Stevens, Chapter 7

Upload: reynold-quinn

Post on 24-Dec-2015

214 views

Category:

Documents


0 download

TRANSCRIPT

cs423-cotter 1

Example Client Program

Reference

Comer & Stevens, Chapter 7

cs423-cotter 2

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]

cs423-cotter 3

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”);}

cs423-cotter 4

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;

cs423-cotter 5

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);

cs423-cotter 6

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;}

cs423-cotter 7

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

cs423-cotter 8

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);

}

9

tcpecho ( ) – argument Switch#include <stdlib.h>,<stdio.h>,<string.h>,<winsock.h>voidTCPecho(), 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);

cs423-cotter 10

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);

}

cs423-cotter 11

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);

}

cs423-cotter 12

UDPecho.cppvoid 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);

}

}

cs423-cotter 13

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);

}

cs423-cotter 14

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*/

cs423-cotter 15

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);

cs423-cotter 16

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;

cs423-cotter 17

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());

cs423-cotter 18

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 () */

cs423-cotter 19

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;

cs423-cotter 20

UDPecho_cnls.cpp – v2switch (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;

cs423-cotter 21

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;

}

cs423-cotter 22

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;

cs423-cotter 23

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); }

cs423-cotter 24

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); }

cs423-cotter 25

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;

cs423-cotter 26

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 () */

cs423-cotter 27

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>