Solved

simple HTTP client use wsock func.

Posted on 2000-05-17
7
297 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
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

707 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now