home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / winsock / simple / simplec.c < prev    next >
C/C++ Source or Header  |  1997-10-08  |  6KB  |  196 lines

  1. /******************************************************************************\
  2. * simplec.c - Simple TCP/UDP client using Winsock 1.1
  3. *       This is a part of the Microsoft Source Code Samples.
  4. *       Copyright 1996-1997 Microsoft Corporation.
  5. *       All rights reserved.
  6. *       This source code is only intended as a supplement to
  7. *       Microsoft Development Tools and/or WinHelp documentation.
  8. *       See these sources for detailed information regarding the
  9. *       Microsoft samples programs.
  10. \******************************************************************************/
  11.  
  12. #define WIN32_LEAN_AND_MEAN
  13. #include <winsock2.h>
  14. #include <stdlib.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17.  
  18. #define DEFAULT_PORT 5001
  19. #define DEFAULT_PROTO SOCK_STREAM // TCP
  20.  
  21. void Usage(char *progname) {
  22.     fprintf(stderr,"Usage\n%s -p [protocol] -n [server] -e [endpoint] \
  23.     -l [iterations]\n",
  24.         progname);
  25.     fprintf(stderr,"Where:\n\tprotocol is one of TCP or UDP\n");
  26.     fprintf(stderr,"\tserver is the IP address or name of server\n");
  27.     fprintf(stderr,"\tendpoint is the port to listen on\n");
  28.     fprintf(stderr,"\titerations is the number of loops to execute\n");
  29.     fprintf(stderr,"\t(-l by itself makes client run in an infinite loop,");
  30.     fprintf(stderr," Hit Ctrl-C to terminate it)\n");
  31.     fprintf(stderr,"Defaults are TCP , localhost and 5001\n");
  32.     WSACleanup();
  33.     exit(1);
  34. }
  35. int main(int argc, char **argv) {
  36.  
  37.     char Buffer[128];
  38.     char *server_name= "localhost";
  39.     unsigned short port = DEFAULT_PORT;
  40.     int retval, loopflag=0;
  41.     int i, loopcount,maxloop=-1;
  42.     unsigned int addr;
  43.     int socket_type = DEFAULT_PROTO;
  44.     struct sockaddr_in server;
  45.     struct hostent *hp;
  46.     WSADATA wsaData;
  47.     SOCKET  conn_socket;
  48.  
  49.     if (argc >1) {
  50.         for(i=1;i <argc;i++) {
  51.             if ( (argv[i][0] == '-') || (argv[i][0] == '/') ) {
  52.                 switch(tolower(argv[i][1])) {
  53.                     case 'p':
  54.                         if (!stricmp(argv[i+1], "TCP") )
  55.                             socket_type = SOCK_STREAM;
  56.                         else if (!stricmp(argv[i+1], "UDP") )
  57.                             socket_type = SOCK_DGRAM;
  58.                         else
  59.                             Usage(argv[0]);
  60.                         i++;
  61.                         break;
  62.  
  63.                     case 'n':
  64.                         server_name = argv[++i];
  65.                         break;
  66.                     case 'e':
  67.                         port = atoi(argv[++i]);
  68.                         break;
  69.                     case 'l':
  70.                         loopflag =1;
  71.                         if (argv[i+1]) {
  72.                             if (argv[i+1][0] != '-') 
  73.                                 maxloop = atoi(argv[i+1]);
  74.                         }
  75.                         else
  76.                             maxloop = -1;
  77.                         i++;
  78.                         break;
  79.                     default:
  80.                         Usage(argv[0]);
  81.                         break;
  82.                 }
  83.             }
  84.             else
  85.                 Usage(argv[0]);
  86.         }
  87.     }
  88.     
  89.     if (WSAStartup(0x202,&wsaData) == SOCKET_ERROR) {
  90.         fprintf(stderr,"WSAStartup failed with error %d\n",WSAGetLastError());
  91.         WSACleanup();
  92.         return -1;
  93.     }
  94.     
  95.     if (port == 0){
  96.         Usage(argv[0]);
  97.     }
  98.  
  99.     //
  100.     // Attempt to detect if we should call gethostbyname() or
  101.     // gethostbyaddr()
  102.  
  103.     if (isalpha(server_name[0])) {   /* server address is a name */
  104.         hp = gethostbyname(server_name);
  105.     }
  106.     else  { /* Convert nnn.nnn address to a usable one */
  107.         addr = inet_addr(server_name);
  108.         hp = gethostbyaddr((char *)&addr,4,AF_INET);
  109.     }
  110.     if (hp == NULL ) {
  111.         fprintf(stderr,"Client: Cannot resolve address [%s]: Error %d\n",
  112.             server_name,WSAGetLastError());
  113.         WSACleanup();
  114.         exit(1);
  115.     }
  116.  
  117.     //
  118.     // Copy the resolved information into the sockaddr_in structure
  119.     //
  120.     memset(&server,0,sizeof(server));
  121.     memcpy(&(server.sin_addr),hp->h_addr,hp->h_length);
  122.     server.sin_family = hp->h_addrtype;
  123.     server.sin_port = htons(port);
  124.  
  125.     conn_socket = socket(AF_INET,socket_type,0); /* Open a socket */
  126.     if (conn_socket <0 ) {
  127.         fprintf(stderr,"Client: Error Opening socket: Error %d\n",
  128.             WSAGetLastError());
  129.         WSACleanup();
  130.         return -1;
  131.     }
  132.  
  133.     //
  134.     // Notice that nothing in this code is specific to whether we 
  135.     // are using UDP or TCP.
  136.     // We achieve this by using a simple trick.
  137.     //    When connect() is called on a datagram socket, it does not 
  138.     //    actually establish the connection as a stream (TCP) socket
  139.     //    would. Instead, TCP/IP establishes the remote half of the
  140.     //    ( LocalIPAddress, LocalPort, RemoteIP, RemotePort) mapping.
  141.     //    This enables us to use send() and recv() on datagram sockets,
  142.     //    instead of recvfrom() and sendto()
  143.  
  144.  
  145.     printf("Client connecting to: %s\n",hp->h_name);
  146.     if (connect(conn_socket,(struct sockaddr*)&server,sizeof(server))
  147.         == SOCKET_ERROR) {
  148.         fprintf(stderr,"connect() failed: %d\n",WSAGetLastError());
  149.         WSACleanup();
  150.         return -1;
  151.     }
  152.  
  153.     // cook up a string to send
  154.     //
  155.     loopcount =0;
  156.     while(1) {
  157.         wsprintf(Buffer,"This is a small test message [number %d]",loopcount++);
  158.         retval = send(conn_socket,Buffer,sizeof(Buffer),0);
  159.         if (retval == SOCKET_ERROR) {
  160.             fprintf(stderr,"send() failed: error %d\n",WSAGetLastError());
  161.             WSACleanup();
  162.             return -1;
  163.         }
  164.         printf("Sent Data [%s]\n",Buffer);
  165.         retval = recv(conn_socket,Buffer,sizeof (Buffer),0 );
  166.         if (retval == SOCKET_ERROR) {
  167.             fprintf(stderr,"recv() failed: error %d\n",WSAGetLastError());
  168.             closesocket(conn_socket);
  169.             WSACleanup();
  170.             return -1;
  171.         }
  172.         //
  173.         // We are not likely to see this with UDP, since there is no
  174.         // 'connection' established. 
  175.         //
  176.         if (retval == 0) {
  177.             printf("Server closed connection\n");
  178.             closesocket(conn_socket);
  179.             WSACleanup();
  180.             return -1;
  181.         }
  182.         printf("Received %d bytes, data [%s] from server\n",retval,Buffer);
  183.         if (!loopflag){
  184.             printf("Terminating connection\n");
  185.             break;
  186.         }
  187.         else {
  188.             if ( (loopcount >= maxloop) && (maxloop >0) )
  189.                 break;
  190.         }
  191.     }
  192.     closesocket(conn_socket);
  193.     WSACleanup();
  194. }
  195.