BKnet
asked on
simple HTTP client use wsock func.
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.
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.
ASKER
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.
Can you show me a program (source code C++) ?
Thanks.
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
There's a sample about using Internet Functions to reteive a file through HTTP.
http://www.codeproject.com/internet/downloaddlg.asp
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(lo cal)) == 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(buffe r) + 1)) != NULL)
{
strcpy(incoming,buffer);
if(ioctlsocket(client,FION READ,&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(e xtra),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;
}
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
{
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(lo
{
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)
{
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(
{
printf("Recive failed on socket ...!\n");
return NULL;
}
buffer[size] = '\0';
if((incoming = (char*)malloc(strlen(buffe
{
strcpy(incoming,buffer);
if(ioctlsocket(client,FION
{
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(e
{
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;
}
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(fi le),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
);
char file[] = "GET /default.html HTTP/1.0"
send(client,file,strlen(fi
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
);
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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,&uc Ipaddr[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(lp szBuffer)) ;
//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/f aq.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_VERSIO N,&wsadata ))
{
//FAILURE HAS OCCURRED, EXIT WITH GRACE
return(WSAGetLastError());
}
else
{
//GET THE IP ADDRESS OF THE HOST
lphostent=gethostbyname(lp szHost);
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)*lph ostent->h_ addr_list) ;
if (uchIP != NULL )
{
uchIP[0]=addr_tmp.S_un.S_u n_b.s_b1;
uchIP[1]=addr_tmp.S_un.S_u n_b.s_b2;
uchIP[2]=addr_tmp.S_un.S_u n_b.s_b3;
uchIP[3]=addr_tmp.S_un.S_u n_b.s_b4;
}
nsocket=socket(PF_INET,SOC K_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=A F_INET;
sockaddr_sock.sin_port=hto ns(port_no );
sockaddr_sock.sin_addr=*(( LPIN_ADDR) *lphostent ->h_addr_l ist);
nconnect=connect(nsocket,( struct sockaddr*)&sockaddr_sock,s izeof(SOCK ADDR_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*)(lpsBuf fer + 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(nSo ck,(long)F IONREAD,&n DataAvaila ble);
if (0== read_query)
{
*pBytes=(long)nDataAvailab le;
return 0;
}
else
{
return WSAGetLastError();
}
}
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,&uc
//build the request string, this will be transmitted to the server
wsprintf(lpszRequestString
//transmit the request string
SendCompleteData(
s,
(unsigned char*)lpszRequestString,
lstrlen(lpszRequestString)
int nActualBytesRead=0;
nActualBytesRead = ReadCompleteData ( s,(unsigned char*)lpszBuffer,sizeof(lp
//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)
}
}
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/f
char lpszSrvr[512]="coolsrvr";
fprintf(stderr,"\nHttpClie
fprintf(stderr,"\nExample:
fprintf(stderr,"\nHttpClie
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_VERSIO
{
//FAILURE HAS OCCURRED, EXIT WITH GRACE
return(WSAGetLastError());
}
else
{
//GET THE IP ADDRESS OF THE HOST
lphostent=gethostbyname(lp
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)*lph
if (uchIP != NULL )
{
uchIP[0]=addr_tmp.S_un.S_u
uchIP[1]=addr_tmp.S_un.S_u
uchIP[2]=addr_tmp.S_un.S_u
uchIP[3]=addr_tmp.S_un.S_u
}
nsocket=socket(PF_INET,SOC
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=A
sockaddr_sock.sin_port=hto
sockaddr_sock.sin_addr=*((
nconnect=connect(nsocket,(
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*)(lpsBuf
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(nSo
if (0== read_query)
{
*pBytes=(long)nDataAvailab
return 0;
}
else
{
return WSAGetLastError();
}
}
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.