/************************************************************ Program: Simple Client Example File: client.cpp Author: Ryan Junee - ryan@cs.usyd.edu.au Version: 1.0 Date: 02/09/2001 Revisions: 1.0 02/09/2001 First Version This program creates client that connects to the specified host and port number. It then reads lines from the standard input and sends them to the server. It then reads the response from the server and displays it on the standard output. Note that I have included very little error handling in this example, and lots of things can go wrong in network programs. If you are serious about writing a network app, read Stevens - Unix Network Programming. **************************************************************/ #include "sockio.h" /* Function prototypes */ int establishConnection(char *, int); // Establish a connection to the server void runClient(int); // Does the actual work once the client has connected /** * Main: Called with two arguments, the host and the port number to connect * to. Once connected, the client reads lines from the standard input, sends * them to the server, and prints the server's reponse to the standard * output. */ int main(int argc, char **argv) { int s; // Will hold the socket once connected. /* First handle command line args */ if (argc != 3) { std::cout << "Usage: " << argv[0] << " " << endl; std::cout << " where is the name of the host to connect to, and" << endl; std::cout << " is the port number to connect to." << endl; return 0; } /* Connect to the server */ s = establishConnection(argv[1], atoi(argv[2])); if (s < 0) { std::cerr << "Couldn't establish connection." << endl; return 1; } /* Do the actual work */ runClient(s); return 0; } /** * This function establishes a TCP/IP connection to the given host and * port number, and returns the connected socket. * @param host The host to connect to (e.g. black, www.microsoft.com, ...) * @param portnum The port to connect to * @return A connected socket (or -1 if an error) */ int establishConnection(char *host, int portnum) { int s; // Will hold the socket struct sockaddr_in sa; // Will hold the server's address struct hostent *hp; // Will hold the servers address /* First get the server's address */ hp = gethostbyname(host); // Look up its IP address etc. if (hp == NULL) { // Can't find the IP address, give up. std::cerr << "Couldn't determine server's IP address." << endl; return -1; } /* Set up the address structure that we will connect to */ memset(&sa, 0, sizeof(struct sockaddr_in)); sa.sin_family = hp->h_addrtype; // Set the type (internet socket) sa.sin_port = htons(portnum); // Set the port number sa.sin_addr.s_addr = ((struct in_addr*)hp->h_addr)->s_addr; // Set the IP address. /* Now create the socket (TCP/IP streaming socket using internet addressing) */ if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { // Error creating the socket, give up. std::cerr << "OS was unable to create the socket." << endl; return -1; } /* Connect the socket to the server */ if (connect(s, (struct sockaddr*)&sa, sizeof(struct sockaddr_in)) < 0) { // Socket could not connect to server, give up. std::cerr << "Could not connect to server." << endl; close(s); return -1; } std::cout << "Connected to " << host << " port " << portnum << ". Enter text, or ctrl-d to exit." << endl; return s; } /** * This function does the work once the client has connected to the server. * This is where you will stick your application specific code. This client * simply reads lines from the standard input, sends them to the server, and * prints the server's response to the standard output. Keeps going until an * EOF is encountered. * @param s The socket connected to the server */ void runClient(int s) { char sendline[MAXLINE]; char recvline[MAXLINE]; memset(sendline, 0, MAXLINE); memset(recvline, 0, MAXLINE); // Loop until EOF is encountered. while (cin) { // Read a line from std in cin.getline(sendline, MAXLINE-1); if (cin) { // Append the '\n' character int pos = strlen(sendline); sendline[pos] = '\n'; sendline[pos+1] = '\0'; // Send the line to the server writen(s, sendline, strlen(sendline)); // Get the server's response if (readline(s, recvline, MAXLINE) == 0) { // Server seems to have terminated std::cerr << "Server terminated prematurely." << endl; std::exit(1); } // Print the server's response to the screen std::cout << recvline << endl; } } return; }