Solved

simple HTTP client use wsock func.

Posted on 2000-05-17
7
340 Views
Last Modified: 2012-05-04
Hi..

I need a client HTTP program use the low level of winsock (Ex :recv , send )). (only for GET file from server)

Use C/C++ code.
thanks.
0
Comment
Question by:BKnet
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
7 Comments
 
LVL 4

Expert Comment

by:pellep
ID: 2816729
see http://www.faqs.org/rfcs/rfc1945.html for info on the HTTP 1.0 protocol or
http://www.faqs.org/rfcs/rfc2068.html for info on the HTTP 1.1 protocol.

A simple test would be to use TELNET and connect to port 80 on an arbitrary webserver and send GET. You will see the HTML code of the default page of that server flashing by.
0
 

Author Comment

by:BKnet
ID: 2816857
OK ! I'v read rfc2068 for a week but my program work not well when we merge/split data (gif) file. (it work well for HTML file)
Can you show me a program (source code C++) ?

Thanks.
0
 
LVL 1

Expert Comment

by:yz
ID: 2816895
Why not try Win32 Internet Functions? It should be more easy to implement I guss.

There's a sample about using Internet Functions to reteive a file through HTTP.

http://www.codeproject.com/internet/downloaddlg.asp
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 10

Expert Comment

by:makerp
ID: 2816930
i have a MFC exmaple that gets a file from a webserver and displays it at the cmd line ?

also this might help. its a .c file i wote for a web server. now the client type functions such as conenct are missing but things such as pullIn ect will be fine. you just have to write the driver program.. easy

/*
     Written by          :     Paul Maker
     Date               :     01/03/2000

     Description          : socket routines, these are just wrappers around the
                           socket functions
*/

#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>

int socket_init()
{
     WSADATA wsaData;
     if (WSAStartup(0x202,&wsaData) == SOCKET_ERROR)
     {
          printf("WSAStartup failed with error %d\n",WSAGetLastError());
          WSACleanup();
          return 0;
     }
     return 1;
}

int socket_shutdown()
{
     if (WSACleanup() == SOCKET_ERROR)
     {
          printf("WSACleanup failed with error %d\n",WSAGetLastError());
          return 0;
     }
     return 1;
}

SOCKET createSocket()
{
     SOCKET s;
     s = socket(AF_INET, SOCK_STREAM,0);
     if (s == INVALID_SOCKET)
     {
          printf("socket() failed with error %d\n",WSAGetLastError());
          WSACleanup();
     }
     return s;
}

int bindSocket(SOCKET s,int port,char* ip_address)
{
     struct sockaddr_in local;

     local.sin_family = AF_INET;
     local.sin_addr.s_addr = inet_addr(ip_address);
     local.sin_port = htons(port);

     if(bind(s,(struct sockaddr*)&local,sizeof(local)) == SOCKET_ERROR)
     {
          printf("bind() failed with error %d\n",WSAGetLastError());
          WSACleanup();
          return 0;
     }
     return 1;
}

int listenSocket(SOCKET s, int max_connections)
{
     if (listen(s,max_connections) == SOCKET_ERROR)
     {
          printf("listen() failed with error %d\n",WSAGetLastError());
          WSACleanup();
          return 0;
     }
     return 1;
}

int closeSocket(SOCKET s)
{
     if (closesocket(s) == SOCKET_ERROR)
     {
          printf("closesocket() failed with error %d\n",WSAGetLastError());
          WSACleanup();
          return 0;
     }
     return 1;
}

/* rip a whole request in from the client */
char *pullInRequest(SOCKET client)
{
     char *incoming = NULL, *extra = NULL, buffer[2048] = "";
     int size = 0;
     u_long argp;

     /* get the first bit */
     if((size = recv(client,buffer,sizeof(buffer),0)) == SOCKET_ERROR)
     {
          printf("Recive failed on socket ...!\n");
          return NULL;    
     }
     buffer[size] = '\0';
     if((incoming = (char*)malloc(strlen(buffer) + 1)) != NULL)
     {
          strcpy(incoming,buffer);
          if(ioctlsocket(client,FIONREAD,&argp) == SOCKET_ERROR)
          {
               printf("ioctlsocket - check more read failed ...!\n");    
               free(incoming);
               return NULL;
          }
          else
          {
               if(argp > 0)
               {
                    extra = (char*)malloc(argp + 1);
                    if(extra)
                    {
                         if((size = recv(client,extra,_msize(extra),0)) == SOCKET_ERROR)
                         {
                              printf("Recive failed on socket ...!\n");
                              free(incoming);
                              return NULL;    
                         }    
                         incoming = (char*)realloc(incoming, strlen(incoming) + 2 +strlen(extra));
                         if(incoming)
                         {
                              extra[size] = '\0';
                              strcat(incoming,extra);
                              free(extra);
                         }
                         else
                         {
                              printf("malloc failed whilst reciving extra data ...!\n");
                              free(extra);
                              return NULL;
                         }
                    }
                    else
                    {
                         printf("malloc failed for extra revc data buffer ...!\n");
                         free(incoming);
                         return NULL;
                    }
               }
          }
     }
     return incoming;    
}
0
 
LVL 10

Expert Comment

by:makerp
ID: 2816943
send and connect can be looked under network and IPC services on VC++

char file[] = "GET /default.html HTTP/1.0"

send(client,file,strlen(file),0);

where client is the client socket you have opened and connected.


The Windows Sockets connect function establishes a connection to a specifed socket.

int connect ( SOCKET s,
 
const struct sockaddr FAR* name,
 
int namelen
 
);
 

0
 
LVL 10

Accepted Solution

by:
makerp earned 200 total points
ID: 2817161
heres a connect one i done .... it only reads in the first 2000 chars and the ip and port are hard coded. youll see. i think this will get you started

#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>

int socket_init()
{
     WSADATA wsaData;
     if (WSAStartup(0x202,&wsaData) == SOCKET_ERROR)
     {
          printf("WSAStartup failed with error %d\n",WSAGetLastError());
          WSACleanup();
          return 0;
     }
     return 1;
}

int socket_shutdown()
{
     if (WSACleanup() == SOCKET_ERROR)
     {
          printf("WSACleanup failed with error %d\n",WSAGetLastError());
          return 0;
     }
     return 1;
}

int main(void)
{
     SOCKET s;
     struct sockaddr_in name;
     char buffer[2000];
     int send_amt = 0;

     name.sin_family = AF_INET;
     name.sin_addr.s_addr = inet_addr("10.244.85.221");
     name.sin_port = htons(80);

     if(!socket_init())
     {
          return 0;
     }

     s = socket(AF_INET, SOCK_STREAM,0);
     if (s == INVALID_SOCKET)
     {
          printf("socket() failed with error %d\n",WSAGetLastError());
          WSACleanup();
          return 0;
     }

     if(connect(s,(struct sockaddr*)&name,sizeof(name)) == SOCKET_ERROR)
     {
          printf("connect() failed with error %d\n",WSAGetLastError());
          WSACleanup();
          return 0;
     }
 
     strcpy(buffer,"GET / HTTP/0.9\n\n");
     if((send_amt = send(s,buffer,strlen(buffer),0)) == SOCKET_ERROR)
     {
          printf("send() failed with error %d\n",WSAGetLastError());
          WSACleanup();
          return 0;
     }    
     printf("Waiting for response ...... %i\n",send_amt);

     if((send_amt = recv(s,buffer,sizeof(buffer),0)) == SOCKET_ERROR)
     {
          printf("recv() failed with error %d\n",WSAGetLastError());
          WSACleanup();
          return 0;    
     }

     printf("%s\n",buffer);


     socket_shutdown();
     return 1;
}
0
 
LVL 4

Expert Comment

by:saurabh_dasgupta
ID: 2817472
I have provided a more structured example of retrieving a file from a web server.

The engine code has been split into re-usable functions. You will need to link to ws2_32.lib.

Hope this helps !!


/**
**
**Author:
**  Saurabh Dasgupta
**
**Date:
**    May 17,2000
**
**/

#include    <winsock2.h>
#include    <windows.h>
#include    <stdio.h>

#define _WSOCK_VER_ 0x0202


void ShowUsage();
BOOLEAN ProcessCmdLineArgs(int argc, char **argv, char *lpszHost, char *lpszFile);
int __stdcall Connect(const char *lpszHost,
                      int iPort,
                      SOCKET *sSock,
                      unsigned char *uchIP,
                      int iTiOut);

int __stdcall ReadCompleteData(
                               SOCKET s,
                               unsigned char *lpsBuffer,
                               int nSize);


int __stdcall SendCompleteData(
                               SOCKET s,
                               unsigned char *lpsBuffer,
                               int nSize);


long _stdcall DataAvailable(
                                long nSock ,
                                long *pBytes);


void main(int argc, char **argv)
    {
    char lpszHost[1024]="";
    char lpszFile[1024]="";
    char lpszRequestString[1024]="";
    char lpszBuffer[1024*20]="";

    if (
        ProcessCmdLineArgs(argc, argv,lpszHost,lpszFile) == FALSE)
        {
        fprintf(stderr,"\nInvalid arguments!!");
        ShowUsage();
        exit(1);
        }

    //make a socket connection to the server
    SOCKET s;
    int nError=0;
    unsigned char ucIpaddr[4];
    nError = Connect(lpszHost,80,&s,&ucIpaddr[0],0);

    //build the request string, this will be transmitted to the server
    wsprintf(lpszRequestString,"GET %s\r\n\0.9",lpszFile);

    //transmit the request string
    SendCompleteData(
                    s,
                    (unsigned char*)lpszRequestString,
                    lstrlen(lpszRequestString));

    int nActualBytesRead=0;
    nActualBytesRead = ReadCompleteData ( s,(unsigned char*)lpszBuffer,sizeof(lpszBuffer));

    //check for error
    if (nActualBytesRead <= 0)
        {
        fprintf(stderr,"\nError occurred while reading (%d) ",nActualBytesRead);
        exit(1);
        }
       
    //display all the data to the stdout
    int k=0;
    for (k = 0; k<nActualBytesRead;k++)
        {
        fprintf(stdout,"%c",(char)lpszBuffer[k]);
        }
    }

BOOLEAN ProcessCmdLineArgs(int argc, char **argv, char *lpszHost, char *lpszFile)
    {
    if (argc != 3)
        return FALSE;
    else
        {
        strcpy(lpszHost,argv[1]);
        strcpy(lpszFile,argv[2]);
        return TRUE;
        }
    }

void ShowUsage()
    {
    char lpszFile[512]="/business/faq.htm";
    char lpszSrvr[512]="coolsrvr";

    fprintf(stderr,"\nHttpClie [remote_host] [file_name]\n");
    fprintf(stderr,"\nExample:");
    fprintf(stderr,"\nHttpClie %s  %s",lpszSrvr,lpszFile);
    fprintf(stderr,"\nWill display the contents of  %s retrieved from %s in the stdout",lpszFile,lpszSrvr);
    }

int __stdcall Connect(const char *lpszHost,
                      int iPort,
                      SOCKET *sSock,
                      unsigned char *uchIP,
                      int iTiOut)
      {
    /*
    Inputs:
        iPort:port on the remote server to which you would like to connect
        pSock:pointer to a socket
        uchIP:a pointer to the first element of an array of 'unsigned char',
        this will take the resolved IP address back to the caller.
        iTiOut:specify time out interval if any.

    Description:
        Tries to establish a socket connection to the remote host lpszHost,
    at the port iPort. On success a valid socket descriptor is returned.
    The array uchIp mut be atleast 4 bytes in size, so as to be able to
    accomodate all the 4 bytes of the IP address that will be resolved from the
    host name lpszHost.
    Error:
        On error , the error code obtained from WSAGetLastError() is returned.
    */
      
      //SOCKET VARIABLES
    //the verion of WinSock library depends on the macro  _WSOCK_VER_
       WORD    WINSOCK_VERSION      =_WSOCK_VER_;

    //if user has specified a port number then use that else use the
    //one defined by PORT_NO
    const int PORT_NO = 80;
    int port_no=PORT_NO;
    if (0!=iPort) port_no = iPort;

      WSADATA             wsadata;                              //FOR RETRIEVING STARTUP WINSOCK IMPLEMENTATION INFO
      int                        _error;
      LPHOSTENT             lphostent;            
      SOCKADDR_IN       sockaddr_sock;
      int                        nconnect;
      SOCKET                   nsocket;
      if (WSAStartup(WINSOCK_VERSION,&wsadata))
            {
            //FAILURE HAS OCCURRED, EXIT WITH GRACE
            return(WSAGetLastError());                               
            }
      else
            {
            //GET THE IP ADDRESS OF THE HOST
            lphostent=gethostbyname(lpszHost);
            if (lphostent==NULL)                                          //ERROR HAS OCCURRED IN RETRIEVING HOST IP ADDR
                  {
                  _error=WSAGetLastError();
                  WSACleanup();                                          //CLEAN UP SOCKETS
                  return(_error);
                  }
            else
                  {
            //extract the IP addr in dotted decimal format
            struct in_addr addr_tmp=*((LPIN_ADDR)*lphostent->h_addr_list);
            if (uchIP != NULL )
                {
                uchIP[0]=addr_tmp.S_un.S_un_b.s_b1;
                uchIP[1]=addr_tmp.S_un.S_un_b.s_b2;
                uchIP[2]=addr_tmp.S_un.S_un_b.s_b3;
                uchIP[3]=addr_tmp.S_un.S_un_b.s_b4;
                }
                  nsocket=socket(PF_INET,SOCK_STREAM,0);
                  if (nsocket==INVALID_SOCKET)
                        {
                        //SOCKET CREATION FAILED
                        WSACleanup();                                          //CLEAN UP SOCKETS
                        _error=WSAGetLastError();
                        return(_error);                                     //IF SOCKET  NOT CREATED THEN EXIT THREAD
                        }
                  else
                        {
                        //SOCKET CREATION WAS A SUCCESS, CREATE A CONNECTION
                         sockaddr_sock.sin_family=AF_INET;
                        sockaddr_sock.sin_port=htons(port_no);
                        sockaddr_sock.sin_addr=*((LPIN_ADDR)*lphostent->h_addr_list);
                        nconnect=connect(nsocket,(struct sockaddr*)&sockaddr_sock,sizeof(SOCKADDR_IN));
                        if (nconnect!=0)
                              {
                              _error=WSAGetLastError();
                              return(_error);
                              }
                        else
                              {
                              //CONNECTION WAS A SUCESS, RETURN ZERO
                              *sSock=nsocket;
                              return(0);
                              }
                        }
                  }
            }
      }



int __stdcall ReadCompleteData(
                               SOCKET s,
                               unsigned char *lpsBuffer,
                               int nSize)
      {
    /**
    Inputs:
        SOCKET s:a valid socket descriptor
        unsigned char *lpsBuffer:a valid memory buffer for taking back all the data
        int nSize:the maximum number of bytes that are to be read. This should not
        be more than the capacity of the lpsBuffer memory region.

    Description:
          This function will read from socket s all n bytes and then return.
      it keeps iterating till the
        1)entire n bytes has been read or
        2)there is some error condition.
        3)there are no more bytes to be read, i.e the total no of bytes read
        in this case will be less than nSize
      If succes then n else SOCKET_ERROR

    Return:
        If there was no error, then the total no of bytes that were read are
    returned. If there was an error, then WSAGetLastError is returned.
    **/
    long  bytes_available=0;
      int bytes_read=0;
      int bytes_toberead=0;
      int stat=0;
      while(bytes_read < nSize)
            {
            stat=0;
            bytes_toberead=nSize - bytes_read;
       
            stat=recv(s,(char*)(lpsBuffer + bytes_read), bytes_toberead,0);
            if (stat == SOCKET_ERROR)
            {
            /**
            if error in reading then SOCKET_ERROR ,then return the error code
            **/
                  return stat;    
            }

        if (stat == 0)
            {
            /**
            if connection was closed            
            gracefully from the other side then return the total bytes read, and exit from function here
            **/
            return bytes_read;
            }
            else
                  bytes_read= bytes_read + stat;
            }
      return bytes_read;
      }


int __stdcall SendCompleteData(SOCKET s,unsigned char *lpsBuffer,int nSize)
      {
      int nsend=0;
      int bytes_sent=0;
      int bytes_remain=0;
      while(bytes_sent < nSize)
            {
            bytes_remain=nSize -  bytes_sent;
            nsend = send(s,      (char*) (lpsBuffer + bytes_sent), bytes_remain,0);
            if (nsend == SOCKET_ERROR)
                  return SOCKET_ERROR;
            else
                  bytes_sent+=nsend;
            }
      return bytes_sent;
      }


long _stdcall DataAvailable(long nSock , long *pBytes)
    {
    /**
    Queries a TCP socket to know the number of bytes that are available for
    immediate reading. If success then 0 else error code.
    **/
    long read_query=0;
    unsigned long nDataAvailable=0;
    *pBytes=0;

    read_query=ioctlsocket(nSock,(long)FIONREAD,&nDataAvailable);
    if (0== read_query)
        {
        *pBytes=(long)nDataAvailable;
        return 0;
        }
    else
        {
        return  WSAGetLastError();
        }

    }
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

632 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question