Thread: Help problem in winsock code

  1. #1
    Registered User
    Join Date
    Dec 2008
    Posts
    183

    Help problem in winsock code

    i just got into winsock learning and i found this example but problem it doesnt compile using msv6
    Code:
    /*
     * whois.c
     *
     * (c) Feb 2000 by Gandalf
     *
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <windows.h>
    #include <winsock.h>
    
    
    
    #define WIN32_LEAN_AND_MEAN        /* define win 32 only */
    
    void handle_error(void);           /* Error handler routine */
    void write_file(char *buf);        /* Write details to log file */
    
    int main (int argc, char **argv)
    {
      WORD wVersionRequested;          /* socket dll version info */
      WSADATA wsaData;                 /* data for socket lib initialisation */
      SOCKET sock;                     /* socket details */
      const int BUF_LEN=10000;         /* Buffer size for transfers */
      struct sockaddr_in address;      /* socket address stuff */
      struct hostent * host;           /* host stuff */
      int err;                         /* error trapping */
      float socklib_ver;               /* socket dll version */
      char File_Buf[BUF_LEN];          /* file buffer */
      char DomainName[100];            /* domain name from user */
      char HostName[100];              /* host name from user */
      time_t now;                      /* for date and time */
    
      if (argc < 2)                    /* check we have command line options */
      {
        printf("\nUseage: whois domainname [whois.server]\n");
        exit(0);
      }
    
      strcat(DomainName, argv[1]); /* get domain name from command line */
      strcat(DomainName, "\r\n");  /* add crlf as whois servers expect it */
    
      if (argc == 3)
        strcat(HostName, argv[2]); /* get host name from command line */
      else
        strcat(HostName, "whois.internic.net");
    
       wVersionRequested = MAKEWORD( 1, 1 );
    
       /*
        * We need to call the WSAStartup routine BEFORE we try to use any of
        * the Winsock dll calls.
        */
    
       if ( WSAStartup( wVersionRequested, &wsaData ) != 0 )
         handle_error();
    
       /* Check socket DLL supports 1.1 or higher */
    
       socklib_ver = HIBYTE( wsaData.wVersion ) / 10.0;
       socklib_ver += LOBYTE( wsaData.wVersion );
    
       if ( socklib_ver < 1.1 )
       {
         printf ("\nError: socket library must support 1.1 or greater.\n");
         WSACleanup(); /* clean up before exit */
         exit(0);
       }
    
       /* write current date and time to log file and screen */
    
       time(&now);
       sprintf(File_Buf, "Whois Session Started %.24s.\n\n", ctime(&now));
       write_file(File_Buf);
    
      /*
       * Open a socket. The AF_INET parameter tells windows we want to use the
       * internet. Other parameters for different networking can be chosen e.g.
       * for netbios, IPX etc. The SOCK_STREAM parameter lets windows know we want
       * to use TCP rather than UDP, and the final parameter will always be
       * zero for what we want to do and tells windows to use whatever
       * default communication protocol has been established (eg PPP and IP)
       */
    
       if ( (sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET )
         handle_error();
    
       /* We now need to initialise a couple of variables in the address
        * structure. Once again, to tell windows we are using the internet,
        * and also what port we want to use when connecting to a remote
        * computer. In this case it is port 43 which is the standard port for
        * whois. The htons routine is used to convert the way Intel chips
        * store data in memory, which is different compared to many other computers.
        * The standard is based on Motorola format.
        */
    
       address.sin_family=AF_INET;       /* internet */
       address.sin_port = htons(43);     /* port 43 for whois */
    
       /* write to the log file and screen */
    
       sprintf(File_Buf,"Connecting to %s\n", HostName);
       write_file(File_Buf);
    
       /*
        * host is a pointer to a structure of the predefined type hostent. We
        * need to call gethostbyname with the DNS name we want to use to return
        * a pointer to a hostent structure. This is so we can resolve an IP
        * address from our ISP's nameserver.
        */
    
        if ( (host=gethostbyname(HostName)) == NULL )
          handle_error();
    
        /* we then initialise the address structure with the resolved IP address */
    
        address.sin_addr.s_addr=*((unsigned long *) host->h_addr);
    
        /* Now we're ready to actually connect to the whois server itself */
    
        if ( (connect(sock,(struct sockaddr *) &address, sizeof(address))) != 0)
          handle_error();
    
        /*
         * We should be connected to the whois server at this point
         * so we need to send the domain name and wait for the response. The send
         * and recv routines are always used with TCP. These enable handshaking
         * compared to the sendto and recvfrom routines which are used for UDP
         * protocol, ie without handshaking.
         */
    
        strcpy(File_Buf, DomainName);
        err=send(sock,File_Buf,strlen(File_Buf),0); /* send domain name */
        err=recv(sock,File_Buf,BUF_LEN,0);          /* discard first response */
        err=recv(sock,File_Buf,BUF_LEN,0);          /* get query results back */
        write_file(File_Buf);
    
        /* Always call WSACleanup before exiting */
    
        WSACleanup(); /* clean up before exit */
        exit(0);
      }
    
      void handle_error(void)
      {
        /*
         * Errors are handled by calling the WSAGetLastError routine which
         * will return the last error as one of the following. As we develop
         * this tutorial, we will go into much more detail on what they mean
         * and what caused them.
         */
    
        switch ( WSAGetLastError() )
        {
          case WSANOTINITIALISED :
            printf("Unable to initialise socket.\n");
          break;
          case WSAEAFNOSUPPORT :
            printf("The specified address family is not supported.\n");
          break;
          case WSAEADDRNOTAVAIL :
            printf("Specified address is not available from the local machine.\n");
          break;
          case WSAECONNREFUSED :
            printf("The attempt to connect was forcefully rejected.\n");
            break;
          case WSAEDESTADDRREQ :
            printf("address destination address is required.\n");
          break;
          case WSAEFAULT :
            printf("The namelen argument is incorrect.\n");
          break;
          case WSAEINVAL :
            printf("The socket is not already bound to an address.\n");
          break;
          case WSAEISCONN :
            printf("The socket is already connected.\n");
          break;
          case WSAEADDRINUSE :
            printf("The specified address is already in use.\n");
          break;
          case WSAEMFILE :
            printf("No more file descriptors are available.\n");
          break;
          case WSAENOBUFS :
            printf("No buffer space available. The socket cannot be created.\n");
          break;
          case WSAEPROTONOSUPPORT :
            printf("The specified protocol is not supported.\n");
            break;
          case WSAEPROTOTYPE :
            printf("The specified protocol is the wrong type for this socket.\n");
          break;
          case WSAENETUNREACH :
            printf("The network can't be reached from this host at this time.\n");
          break;
          case WSAENOTSOCK :
             printf("The descriptor is not a socket.\n");
          break;
          case WSAETIMEDOUT :
            printf("Attempt timed out without establishing a connection.\n");
          break;
          case WSAESOCKTNOSUPPORT :
             printf("Socket type is not supported in this address family.\n");
          break;
          case WSAENETDOWN :
            printf("Network subsystem failure.\n");
          break;
          case WSAHOST_NOT_FOUND :
            printf("Authoritative Answer Host not found.\n");
          break;
          case WSATRY_AGAIN :
            printf("Non-Authoritative Host not found or SERVERFAIL.\n");
           break;
          case WSANO_RECOVERY :
             printf("Non recoverable errors, FORMERR, REFUSED, NOTIMP.\n");
          break;
          case WSANO_DATA :
            printf("Valid name, no data record of requested type.\n");
          break;
            case WSAEINPROGRESS :
            printf("address blocking Windows Sockets operation is in progress.\n");
          break;
          case WSAEINTR :
            printf("The (blocking) call was canceled via WSACancelBlockingCall().\n");
          break;
          default :
            printf("Unknown error.\n");
           break;
      }
    
      WSACleanup();
      exit(0);
    }
    
    void write_file(char *buf)
    {
      /* writes results to a log file and also to the screen */
    
      FILE *fp=fopen("whoislog.txt","a+");
      fprintf(fp,"%s\n",buf);
      fclose(fp);
      printf("%s\n",buf);
    }
    i get this errors

    d:\all pro program you did\network learning\winsock part1\main.c(31) : error C2057: expected constant expression
    d:\all pro program you did\network learning\winsock part1\main.c(31) : error C2466: cannot allocate an array of constant size 0
    d:\all pro program you did\network learning\winsock part1\main.c(31) : error C2133: 'File_Buf' : unknown size

    even though the size
    is specified here const int BUF_LEN=10000;

  2. #2
    Registered User
    Join Date
    Dec 2008
    Location
    Black River
    Posts
    128
    Try using:

    #define BUF_LEN 10000

    Also, the macro WIN32_LEAN_AND_MEAN has to go before you #include windows.h

  3. #3
    Registered User
    Join Date
    Dec 2008
    Posts
    183
    i get these errors now main.obj : error LNK2001: unresolved external symbol _recv@16
    main.obj : error LNK2001: unresolved external symbol _send@16
    main.obj : error LNK2001: unresolved external symbol _connect@12
    main.obj : error LNK2001: unresolved external symbol _gethostbyname@4
    main.obj : error LNK2001: unresolved external symbol _htons@4
    main.obj : error LNK2001: unresolved external symbol _socket@12
    main.obj : error LNK2001: unresolved external symbol _WSACleanup@0
    main.obj : error LNK2001: unresolved external symbol _WSAStartup@8
    main.obj : error LNK2001: unresolved external symbol _WSAGetLastError@0
    Debug/winsock part1.exe : fatal error LNK1120: 9 unresolved externals
    Error executing link.exe.

  4. #4
    Registered User
    Join Date
    Dec 2008
    Location
    Black River
    Posts
    128
    I think you have to link against an additional library; I believe it was ws2_32.lib or ws2.lib. Try linking against one of those to see if it works

  5. #5
    Registered User
    Join Date
    Dec 2008
    Posts
    183
    yah it works now why did i need to add that lib ?

  6. #6
    Registered User
    Join Date
    Dec 2008
    Posts
    183
    Code:
    /*
     * whois.c
     *
     * (c) Feb 2000 by Gandalf
     *
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #define WIN32_LEAN_AND_MEAN        /* define win 32 only */
    #include <windows.h>
    #include <winsock.h>
    #pragma comment(lib, "ws2_32.lib")
    #define BUF_LEN 10000         /* Buffer size for transfers */
    
    void handle_error(void);           /* Error handler routine */
    void write_file(char *buf);        /* Write details to log file */
    
    int main (int argc, char **argv)
    {
      WORD wVersionRequested;          /* socket dll version info */
      WSADATA wsaData;                 /* data for socket lib initialisation */
      SOCKET sock;                     /* socket details */
      
      struct sockaddr_in address;      /* socket address stuff */
      struct hostent * host;           /* host stuff */
      int err;                         /* error trapping */
      float socklib_ver;               /* socket dll version */
      char File_Buf[BUF_LEN];          /* file buffer */
      char DomainName[100];            /* domain name from user */
      char HostName[100];              /* host name from user */
      time_t now;                      /* for date and time */
    
      if (argc < 2)                    /* check we have command line options */
      {
        printf("\nUseage: whois domainname [whois.server]\n");
        exit(0);
      }
    
      strcat(DomainName, argv[1]); /* get domain name from command line */
      strcat(DomainName, "\r\n");  /* add crlf as whois servers expect it */
    
      if (argc == 3)
        strcat(HostName, argv[2]); /* get host name from command line */
      else
        strcat(HostName, "whois.internic.net");
    
       wVersionRequested = MAKEWORD( 1, 1 );
    
       /*
        * We need to call the WSAStartup routine BEFORE we try to use any of
        * the Winsock dll calls.
        */
    
       if ( WSAStartup( wVersionRequested, &wsaData ) != 0 )
         handle_error();
    
       /* Check socket DLL supports 1.1 or higher */
    
       socklib_ver = HIBYTE( wsaData.wVersion ) / 10.0;
       socklib_ver += LOBYTE( wsaData.wVersion );
    
       if ( socklib_ver < 1.1 )
       {
         printf ("\nError: socket library must support 1.1 or greater.\n");
         WSACleanup(); /* clean up before exit */
         exit(0);
       }
    
       /* write current date and time to log file and screen */
    
       time(&now);
       sprintf(File_Buf, "Whois Session Started %.24s.\n\n", ctime(&now));
       write_file(File_Buf);
    
      /*
       * Open a socket. The AF_INET parameter tells windows we want to use the
       * internet. Other parameters for different networking can be chosen e.g.
       * for netbios, IPX etc. The SOCK_STREAM parameter lets windows know we want
       * to use TCP rather than UDP, and the final parameter will always be
       * zero for what we want to do and tells windows to use whatever
       * default communication protocol has been established (eg PPP and IP)
       */
    
       if ( (sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET )
         handle_error();
    
       /* We now need to initialise a couple of variables in the address
        * structure. Once again, to tell windows we are using the internet,
        * and also what port we want to use when connecting to a remote
        * computer. In this case it is port 43 which is the standard port for
        * whois. The htons routine is used to convert the way Intel chips
        * store data in memory, which is different compared to many other computers.
        * The standard is based on Motorola format.
        */
    
       address.sin_family=AF_INET;       /* internet */
       address.sin_port = htons(43);     /* port 43 for whois */
    
       /* write to the log file and screen */
    
       sprintf(File_Buf,"Connecting to %s\n", HostName);
       write_file(File_Buf);
    
       /*
        * host is a pointer to a structure of the predefined type hostent. We
        * need to call gethostbyname with the DNS name we want to use to return
        * a pointer to a hostent structure. This is so we can resolve an IP
        * address from our ISP's nameserver.
        */
    
        if ( (host=gethostbyname(HostName)) == NULL )
          handle_error();
    
        /* we then initialise the address structure with the resolved IP address */
    
        address.sin_addr.s_addr=*((unsigned long *) host->h_addr);
    
        /* Now we're ready to actually connect to the whois server itself */
    
        if ( (connect(sock,(struct sockaddr *) &address, sizeof(address))) != 0)
          handle_error();
    
        /*
         * We should be connected to the whois server at this point
         * so we need to send the domain name and wait for the response. The send
         * and recv routines are always used with TCP. These enable handshaking
         * compared to the sendto and recvfrom routines which are used for UDP
         * protocol, ie without handshaking.
         */
    
        strcpy(File_Buf, DomainName);
        err=send(sock,File_Buf,strlen(File_Buf),0); /* send domain name */
        err=recv(sock,File_Buf,BUF_LEN,0);          /* discard first response */
        err=recv(sock,File_Buf,BUF_LEN,0);          /* get query results back */
        write_file(File_Buf);
    
        /* Always call WSACleanup before exiting */
    
        WSACleanup(); /* clean up before exit */
        exit(0);
      }
    
      void handle_error(void)
      {
        /*
         * Errors are handled by calling the WSAGetLastError routine which
         * will return the last error as one of the following. As we develop
         * this tutorial, we will go into much more detail on what they mean
         * and what caused them.
         */
    
        switch ( WSAGetLastError() )
        {
          case WSANOTINITIALISED :
            printf("Unable to initialise socket.\n");
          break;
          case WSAEAFNOSUPPORT :
            printf("The specified address family is not supported.\n");
          break;
          case WSAEADDRNOTAVAIL :
            printf("Specified address is not available from the local machine.\n");
          break;
          case WSAECONNREFUSED :
            printf("The attempt to connect was forcefully rejected.\n");
            break;
          case WSAEDESTADDRREQ :
            printf("address destination address is required.\n");
          break;
          case WSAEFAULT :
            printf("The namelen argument is incorrect.\n");
          break;
          case WSAEINVAL :
            printf("The socket is not already bound to an address.\n");
          break;
          case WSAEISCONN :
            printf("The socket is already connected.\n");
          break;
          case WSAEADDRINUSE :
            printf("The specified address is already in use.\n");
          break;
          case WSAEMFILE :
            printf("No more file descriptors are available.\n");
          break;
          case WSAENOBUFS :
            printf("No buffer space available. The socket cannot be created.\n");
          break;
          case WSAEPROTONOSUPPORT :
            printf("The specified protocol is not supported.\n");
            break;
          case WSAEPROTOTYPE :
            printf("The specified protocol is the wrong type for this socket.\n");
          break;
          case WSAENETUNREACH :
            printf("The network can't be reached from this host at this time.\n");
          break;
          case WSAENOTSOCK :
             printf("The descriptor is not a socket.\n");
          break;
          case WSAETIMEDOUT :
            printf("Attempt timed out without establishing a connection.\n");
          break;
          case WSAESOCKTNOSUPPORT :
             printf("Socket type is not supported in this address family.\n");
          break;
          case WSAENETDOWN :
            printf("Network subsystem failure.\n");
          break;
          case WSAHOST_NOT_FOUND :
            printf("Authoritative Answer Host not found.\n");
          break;
          case WSATRY_AGAIN :
            printf("Non-Authoritative Host not found or SERVERFAIL.\n");
           break;
          case WSANO_RECOVERY :
             printf("Non recoverable errors, FORMERR, REFUSED, NOTIMP.\n");
          break;
          case WSANO_DATA :
            printf("Valid name, no data record of requested type.\n");
          break;
            case WSAEINPROGRESS :
            printf("address blocking Windows Sockets operation is in progress.\n");
          break;
          case WSAEINTR :
            printf("The (blocking) call was canceled via WSACancelBlockingCall().\n");
          break;
          default :
            printf("Unknown error.\n");
           break;
      }
    
      WSACleanup();
      exit(0);
    }
    
    void write_file(char *buf)
    {
      /* writes results to a log file and also to the screen */
    
      FILE *fp=fopen("whoislog.txt","a+");
      fprintf(fp,"%s\n",buf);
      fclose(fp);
      printf("%s\n",buf);
    }

  7. #7
    Registered User
    Join Date
    Dec 2008
    Posts
    183
    i thought just header was enough ? do alawys have to include this lib ? or what?

  8. #8
    Registered User
    Join Date
    Dec 2008
    Location
    Black River
    Posts
    128
    Quote Originally Posted by lolguy View Post
    i thought just header was enough ?
    Header files typically only have declarations for functions, structs, etc. The definitions are almost always on external libraries.

    do alawys have to include this lib ?
    Some of the functions from winsock.h require this lib; some do not. If you get linking errors like before, check the documentation and see if you need to link against an external library.

  9. #9
    Registered User
    Join Date
    Dec 2008
    Posts
    183
    okay thanks btw is there any book recomdation on networking because tutrials are okay but they dunt explain that much and also one recomdended me to book before but it was C# not c

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with my morse code program
    By justin87 in forum C++ Programming
    Replies: 1
    Last Post: 10-21-2007, 05:23 PM
  2. Problem compiling simple code examples
    By Wintersun in forum Windows Programming
    Replies: 8
    Last Post: 08-14-2007, 10:30 AM
  3. Winsock Webserver Problem
    By RunningBon in forum Networking/Device Communication
    Replies: 4
    Last Post: 06-08-2005, 04:05 PM
  4. Replies: 5
    Last Post: 12-03-2003, 05:47 PM
  5. problem with my code
    By stilllearning in forum C++ Programming
    Replies: 3
    Last Post: 04-08-2003, 03:02 PM