• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 873
  • Last Modified:

How to create a Socket program in VC++(URGENT)

Hi,
    I am trying to compile a simple socket program ( the which I got ot from net). But I am facing the problems in linking. The linker is not able to resolve the function pointers in winsock.h.
      I never worked with VC++ sockets, I have experience on unix, ans OS/2 where the things are very clear( in the sense without cosidereing the details of importing dlls).

  Could some body tell how to compile this and necessity of loading the dll( the version of it). I am pasting the code below, please add comments in code directly
------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <winsock.h>

#define NUL             '\0' /* ASCII NUL character */

/* function prototypes */
void do_sock( SOCKET sock );          /* socket to read and write */
void pWSAerror(char *text );           /* error message text */


void main()
    {
       char *argv[] = {        /* fake command argument list */
      "sockprog",               /* this program's name */
      "river.it.gvsu.edu",      /* host name */
      "echo"                    /* echo service name */
      };
    WORD   wVersionRequested; /* requested version WinSock API */
    WSADATA wsadata;        /* Windows Sockets API data */
    SOCKET sock;            /* socket descriptor */
    struct hostent FAR *hp; /* ptr to host info struct */
    struct servent FAR *sp; /* ptr to service info struct */
    struct sockaddr_in server; /* socket address and port */
    int    stat;            /* status return value */

 /* Send a message to the text window (stdin/stderr/stdout) */
    printf( "SOCKPROG Windows Socket Demo Program (QuickWin).\n" );

    /*------------------------------------------------------*/
    /* Start up the Windows Sockets API.                    */
    /* We are looking for an API version 1.1 implementation.*/
    /*------------------------------------------------------*/

    printf( "Starting WinSock API...\n" );    
    wVersionRequested = 0x0101;
    stat = WSAStartup( wVersionRequested, &wsadata );
    if (stat != 0)
        {
        printf( "No usable WINSOCK.DLL found\n" );
        exit( 1 );
        }
    else if (LOBYTE( wsadata.wVersion) != 1  &&
             HIBYTE( wsadata.wVersion) != 1)
        {
        printf( "WINSOCK.DLL does not support version 1.1\n" );
        WSACleanup();
        exit( 1 );
        }
       
    printf("WINSOCK description: %s\n", wsadata.szDescription);
    printf("WINSOCK vendor info: %s\n", wsadata.lpVendorInfo);
   
     /*------------------------------------------------------*/
    /* Create the socket                                    */
    /*------------------------------------------------------*/
   
    sock = socket( AF_INET, SOCK_STREAM, 0 );
    if (sock == INVALID_SOCKET)
        {
        pWSAerror( "could not create socket" );
        WSACleanup();
        exit( 1 );
        }

       /*------------------------------------------------------*/
    /* Connect (and bind) the socket to the service         */
    /* and provider.                                        */
    /*------------------------------------------------------*/
   
    hp = gethostbyname( argv[1] );
    if (hp == NULL)
        {
        printf( "could not get host by name %s\n", argv[1] );
        pWSAerror( "no host" );
        WSACleanup();
        exit( 1 );
        }
       
    memset( &server, 0, sizeof(server) );
    memcpy( &server.sin_addr, hp->h_addr, hp->h_length );
    server.sin_family = hp->h_addrtype;
   
    sp = getservbyname( argv[2], "tcp" );
    if (sp == NULL)
        {
        if (isdigit(*(argv[2])))
            /* get service by number */
            /* we need to swap byte order here */
            server.sin_port = htons( atoi(argv[2]) );
        else
            {
            printf( "could not find tcp service %s\n", argv[2] );
            pWSAerror( "no service" );
            WSACleanup();
            exit( 1 );
            }
        }
    else
        server.sin_port = sp->s_port;
       
    stat = connect( sock, (const struct sockaddr FAR *)&server,
      sizeof(server) );
    if (stat != 0)
        {
        pWSAerror( "could not connect" );
        WSACleanup();
        exit( 1 );
        }
       
    printf( "successful socket established\n" );
 
    /*------------------------------------------------------*/
    /* Read from stdin and write to socket, and             */
    /* read from socket and write to stdout.                */
    /*------------------------------------------------------*/
       
    do_sock( sock );

    /*------------------------------------------------------*/
    /* Clean up and go home.                                */
    /*------------------------------------------------------*/

    shutdown( sock, 2 );
    closesocket( sock );
    WSACleanup();
    exit( 0 );
    }


/* The function do_sock will read a line from stdin and send*/
/* that line via the socket to the ECHO server.  It will    */
/* then read a line from the ECHO server via the socket and */
/* write it to the stdout device.                           */
/* Note the assumption that the ECHO server will return the */
/* same number of characters as are sent to it.  If it      */
/* return fewer characters, this function may wait          */
/* indefinitely.                                            */
   
#define MAXLINE 256

void do_sock( SOCKET sock )               /* socket to read and write */
    {
    int loopy;                  /* loop control */
    int nb;                     /* number of bytes */
    char buffer[MAXLINE];       /* line read from stdin */
    int bufcnt;                 /* no. of chars in buffer */                            
    char sockbuf[MAXLINE];      /* chars read from socket */
    int sockcnt;                /* no. of chars in sockbuf */

    /* Repeat until "quit" is entered. */
    loopy = 1;
    while (loopy)
        {
       
        /*--------------------------------------------------*/
        /* Get a line of text from stdin.  If it is the     */
        /* string "quit" or an empty line, we will quit     */
        /* and return.  Otherwise, we will go on and send   */
        /* the line to the ECHO server.                     */
        /*--------------------------------------------------*/
       
        printf("Enter command for server (or quit)\n");
        if (gets( buffer ) == NULL)
            loopy = 0;
        else if (strcmp( buffer, "quit" ) == 0)
            loopy = 0;
        else
            {
                         /*----------------------------------------------*/
            /* Send the line of text to the ECHO server.    */
            /*----------------------------------------------*/
            bufcnt = strlen( buffer );
            nb = send( sock, buffer, bufcnt, 0 );
            if (nb != bufcnt)
                {
                pWSAerror( "error writing to socket" );
                return;
                }

        /*----------------------------------------------*/
            /* Read the response from the ECHO server.      */
            /* Note that if we do not get enough characters */
            /* back, we will wait here indefinitely.        */
            /*----------------------------------------------*/
            sockcnt = 0;
            while (sockcnt < bufcnt)
                {
                nb = recv( sock, &sockbuf[sockcnt],
                  MAXLINE-sockcnt-1, 0 );
                if (nb == SOCKET_ERROR)
                    {
                    pWSAerror( "error reading from socket" );
                    return;
                    }
                else if (nb == 0) /* socket closed by server */
                    return;
                else              /* read OK, inc char count */
                    sockcnt += nb;
                   
                /*------------------------------------------*/
                /* Write the response to stdout.            */
                /*------------------------------------------*/
                sockbuf[sockcnt] = NUL;
                printf( "%s\n", sockbuf );
                }
            }    
           
        } /* end while loopy */
    return;
    }


/* The function pWSAerror is used to print a Windows Sockets*/
/* API error message.  This function is used instead of     */
/* perror because the WinSock API does not return its error */
/* codes via errno.                                         */
 
   void pWSAerror(
    char *text )            /* error message text to display */
    {
    int err;                /* Winsock error code */
   
    err = WSAGetLastError();
    printf( "%s, error %d\n", text, err );
   
    /* As a future enhancement, this routine could         */
    /* implement a switch on the error code and print a    */
    /* specific text message for each type of error.       */
   
    return;
    }
------------------------------------------------------------------------------------

Thanks
shivaki

0
shivaki
Asked:
shivaki
1 Solution
 
WxWCommented:
Tell me excactly the linker error .
Maybe try including winsock2.h
0
 
WxWCommented:
Maybe you need to link against the library of WS2_32.DLL . Create an import  LIB file using the VC++ ( LIB tool I think ) , then include the generated LIB file in your project.
0
 
yodanCommented:
For MSVC6.0:

Use the MSDN for one of those functions (api's in winsock.h) - for instance gethostbyaddr() - and read the end part of the topic:
QuickInfo
  Windows NT: Yes
  Windows: Yes
  Windows CE: Use version 1.0 and later.
  Header: Declared in winsock2.h.
  Import Library: Link with ws2_32.lib.


then add the ws2_32.lib to your project (project| '?Linking?' tab) where there are already declared some other (default) libraries, and then relink.
As I looked it is for winsockets 2 so if you need winsock 1 (don't know when change occurred... VC6?) you just read MSDN and add the correct lib, possibly [win]sock32.lib.

BTW, you may recreate a new project MFC App project and skip the wizard tabs until it asks if you want "...sockets...", create it, then read the Project linking libs... OK?

In MSVC5.0, can be a bit different but search API in MSDN too,
(don't have MSDN for VC5 here):
 On the top topics start selecting one of them like 'Scope', 'Overview', ..., until you find description of lib and dll.
Relink.

I believe this to be enough.

Ask me, if more needed.
0
 
shivakiAuthor Commented:
Thanks yodan,
   It is working. Thanks a lot, I may fire more questions in future, please reply to them also.
-shivaki
0
 
klecki_2000Commented:
In the code above , in the line
 printf("WINSOCK vendor info: %s\n", wsadata.lpVendorInfo);
Vendor Ignored for Windows Sockets version 2 and onward  , so you can get an error on running time.
This is because the architecture of Windows Sockets has been changed in version 2 to support multiple providers , so use another function to retrieve vendor info like
getsockopt .
 
0

Featured Post

[Webinar] Kill tickets & tabs using PowerShell

Are you tired of cycling through the same browser tabs everyday to close the same repetitive tickets? In this webinar JumpCloud will show how you can leverage RESTful APIs to build your own PowerShell modules to kill tickets & tabs using the PowerShell command Invoke-RestMethod.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now