/* ******************************************************************************* ** FILE: TCP_socket_client.C -- example program demonstrating usage of ** network programming library using UNIX-like stream sockets. ** ** PRODUCT: TCPware for VMS ** ** VERSION: V5.3 ** ** Copyright (c) 1997 by ** Process Software Corporation ** Framingham, Massachusetts ** ** This software is furnished under a license for use on a ** single computer system and may be copied only with the ** inclusion of the above copyright notice. This software, or ** any other copies thereof, may not be provided or otherwise ** made available to any other person except for use on such ** system and to one who agrees to these license terms. Title ** to and ownership of the software shall at all times remain ** in Process Software Corporation's name. ** ** The information in this document is subject to change ** without notice and should not be construed as a commitment ** by Process Software Corporation. Process Software ** Corporation assumes no responsibility for any errors that ** may appear in this document. ** ** ** ABSTRACT: ** ** TCP_socket_server.c and TCP_socket_client.c are a pair of example programs ** illustrating the use of UNIX-like stream sockets. ** ** ** ** CLIENT SEQUENCE OF OPERATIONS: ** 1. Create a socket: socket() ** 2. Open connection to server: connect() ** 3. Exchange data: send()/recv() or read()/write() ** 3. Close the socket: close() ** ** ** BUILDING EXECUTABLES: ** ** 1. on VAX : ** with VAXC: ** $ CC TCP_SOCKET_CLIENT.C ** $ LINK TCP_SOCKET_CLIENT, TCPWARE:UCX$IPC/LIB, - ** SYS$INPUT/OPTIONS ** SYS$SHARE:VAXCRTL/SHARE ** ** Instead of UCX's BG devices, TCpware's ** socket library with TCP devices can be used. ** ("/DEFINE=TCPWARE" allows read() etc. to be redefined to a socket function.): ** ** $ CC TCP_SOCKET_CLIENT.C /DEFINE=TCPWARE ** $ LINK TCP_SOCKET_CLIENT, SYS$INPUT/OPTIONS ** SYS$SHARE:TCPWARE_SOCKLIB_SHR/SHARE ** SYS$SHARE:VAXCRTL/SHARE ** ** with DECC: ** $ CC/DECC/PREFIX_LIBRARY_ENTRIES=ALL TCP_SOCKET_CLIENT.C ** $ LINK TCP_SOCKET_CLIENT ** ** 2. on ALPHA: $ CC/DECC/PREFIX_LIBRARY_ENTRIES=ALL TCP_SOCKET_CLIENT.C ** $ LINK TCP_SOCKET_CLIENT ** ******************************************************************************* ** REQUEST: If you have comments, please send them to "support@process.com" ******************************************************************************* */ #include /* Standard C i/o */ #include #include #include #include #include #include #include /* ** Service information */ #define SERVER_PORT 2048 /* if getservbyname fails, use this port number */ #define SERVICE "test_echo" #define PROTO "tcp" /* ** Net header needed since TCP function may not transmit entire message. ** If using this, it needs to be in both server and client. */ struct net_msg_hdr_struct { long msg_len; long seq_num; /* useful incase of resends */ }; #ifdef VAXC #ifdef TCPWARE # define read socket_read # define write socket_write # define close socket_close # define perror pneterror #endif /* TCPWARE */ /* function prototypes */ int socket_read( int s, char * buffer, int buflen); int socket_write( int s, char * buffer, int buflen); int socket_close( int s); #endif /* VAXC */ main() { int client_socket; int got_host; int addrlen; int bytes; char server_name[200]; int bytes_left; char buffer[1024]; char *c_P; int io_OK; /* boolean continue status */ struct sockaddr_in server_adr; struct servent *servent_P; struct hostent *hostent_P; struct net_msg_hdr_struct *net_msg_hdr_P; /* ** Get server port number for named serice. ** If unknown ( == 0 or = -1), use default define. */ memset( &server_adr, 0, sizeof( server_adr) ); if ( (int)(servent_P = getservbyname( SERVICE, PROTO)) > 0) server_adr.sin_port = servent_P->s_port; else server_adr.sin_port = htons(SERVER_PORT); printf("Will connect to server port #: %d\n\n", ntohs(server_adr.sin_port)); /* Query user for server name and get corresponding internet address. */ for (got_host = FALSE; got_host == FALSE; ) { printf("Enter name of remote host (e.g. localhost) : "); gets( server_name); if ((hostent_P = gethostbyname(server_name)) == NULL) { printf("Error, gethostbyname failed\n"); } else { got_host = TRUE; server_adr.sin_family = hostent_P->h_addrtype; server_adr.sin_addr = *( (struct in_addr *)(hostent_P->h_addr) ); } } /* Create socket */ if ( (client_socket = socket(AF_INET, SOCK_STREAM, 0) ) < 0) { perror("socket"); exit(1); } /*Connect to server */ if ( connect( client_socket, (struct sockaddr *)&server_adr, sizeof(server_adr) ) < 0) { perror("connect"); exit(1); } /* ** Keep getting input string, sending it to the server and reading the ** server's reply, till EOF is input. */ net_msg_hdr_P = (struct net_msg_hdr_struct *)&buffer; for (io_OK = TRUE, net_msg_hdr_P->seq_num = 1; io_OK; net_msg_hdr_P->seq_num++) { /* ** Prepare message to send: ** Setup message (Replace with your application function.) ** Add application header w/ message length. ** Calculate total length to send. */ c_P = &buffer[0] + sizeof(* net_msg_hdr_P); printf("Input string to echo:\n"); if ( gets( c_P) == NULL) io_OK = FALSE; net_msg_hdr_P->msg_len = strlen( buffer + sizeof(* net_msg_hdr_P) ); bytes_left = net_msg_hdr_P->msg_len + sizeof(* net_msg_hdr_P); /* ** Send message: ** Keep writing till full message is sent, including header. */ for (c_P = &buffer[0]; io_OK && bytes_left > 0; bytes_left -= bytes, c_P += bytes) { bytes = write( client_socket, c_P, bytes_left); if (bytes < 0) { perror( "Error sending message."); io_OK = FALSE; } } /* break out of this loop if bad IO */ if (! io_OK) break; /* ** Receive message: ** Read to find total message length. ** Error if bytes = -1 or if too small. */ bytes = read( client_socket, net_msg_hdr_P, sizeof( *net_msg_hdr_P) ); if ( bytes < sizeof( *net_msg_hdr_P) ) { perror( "Error reading net_msg_hdr."); break; } /* Keep reading till entire message read or IO error. */ for (c_P = &buffer[0] + sizeof( *net_msg_hdr_P), bytes_left = net_msg_hdr_P->msg_len; io_OK == TRUE && bytes_left > 0; bytes_left -= bytes, c_P += bytes) { bytes = read( client_socket, c_P, bytes_left); /* If OK, print message received in this read */ if ( bytes > 0 ) { *(c_P + bytes) = '\0'; /* terminate for printf() */ printf("Read %02d characters:\n%s\n\n", bytes, c_P); } else { io_OK = FALSE; perror( "Error reading message."); break; } /* Output returned message */ if (! io_OK) { c_P = &buffer[0] + sizeof( *net_msg_hdr_P); *(c_P + net_msg_hdr_P->msg_len) = '\0'; printf( "Echoed string: %s\n"); } } } /* Close the socket */ close(client_socket); }