Example: A Socket-Based Client
Program 11-2, clientNP. The conversion is straightforward, with several small differences.
- Rather than locating a server using mailslots, the user enters the IP address on the command line. If the IP address is not specified, the default address is 127.0.0.1, which indicates the current system.
- Functions for sending and receiving messages, such as ReceiveMessage, are used but are not shown here.
- The port number, SERVER_PORT, is defined in the header file, ClntSrvr.h.
While the code is written for Windows, there are no Windows dependencies other than the WSA calls.
Program 12-1. clientSK: Socket-Based Client
/* Chapter 12. clientSK.c */
/* Single-threaded command line client. */
/* WINDOWS SOCKETS VERSION. */
/* Reads a sequence of commands to send to a server process */
/* over a socket connection. Wait for and display response. */
#define _NOEXCLUSIONS /* Required to include socket definitions. */
#include "EvryThng.h"
#include "ClntSrvr.h" /* Defines request and response records. */
/* Message functions for request and response. */
/* ReceiveResponseMessage also prints the received messages. */
static DWORD SendRequestMessage (REQUEST *, SOCKET);
static DWORD ReceiveResponseMessage (RESPONSE *, SOCKET);
struct sockaddr_in ClientSAddr; /* Clients's socket address. */
int _tmain (DWORD argc, LPTSTR argv [])
{
SOCKET ClientSock = INVALID_SOCKET;
REQUEST Request; /* See ClntSrvr.h. */
RESPONSE Response; /* See ClntSrvr.h. */
WSADATA WSStartData; /* Socket library data structure. */
BOOL Quit = FALSE;
DWORD ConVal, j;
TCHAR PromptMsg [] = _T ("\nEnter Command> ");
TCHAR Req [MAX_RQRS_LEN];
TCHAR QuitMsg [] = _T ("$Quit");
/* Request: shut down client. */
TCHAR ShutMsg [] = _T ("$ShutDownServer");
/* Stop all threads. */
CHAR DefaultIPAddr [] = "127.0.0.1"; /* Local system. */
/* Initialize the WSA library, Ver 2.0, although 1.1 will work. */
WSAStartup (MAKEWORD (2, 0), &WSStartData);
/* Connect to the server. */
/* Follow the standard client socket/connect sequence. */
ClientSock = socket (AF_INET, SOCK_STREAM, 0);
memset (&ClientSAddr, 0, sizeof (ClientSAddr));
ClientSAddr.sin_family = AF_INET;
if (argc >= 2)
ClientSAddr.sin_addr.s_addr = inet_addr (argv [1]);
else
ClientSAddr.sin_addr.s_addr = inet_addr (DefaultIPAddr);
ClientSAddr.sin_port = htons (SERVER_PORT);
/* Defined as 1070. */
connect (ClientSock,
(struct sockaddr *) &ClientSAddr, sizeof (ClientSAddr));
/* Main loop to prompt user, send request, receive response. */
while (!Quit) {
_tprintf (_T ("%s"), PromptMsg);
/* Generic input, but command to server must be ASCII. */
_fgetts (Req, MAX_RQRS_LEN-1, stdin);
for (j = 0; j <= _tcslen (Req); j++)
Request.Record [j] = Req [j];
/* Get rid of the new line at the end. */
Request.Record [strlen (Request.Record) - 1] = '\0';
if (strcmp (Request.Record, QuitMsg) == 0 ||
strcmp (Request.Record, ShutMsg) == 0) Quit = TRUE;
SendRequestMessage (&Request, ClientSock);
ReceiveResponseMessage (&Response, ClientSock);
}
shutdown (ClientSock, 2); /* Disallow sends and receives. */
closesocket (ClientSock);
WSACleanup ();
_tprintf (_T ("\n****Leaving client\n"));
return 0;
}
