Hi
I'm adding http 1.1 GET to my project and trying to use �Keep-Alive� HTTP connections to the host, The problem is when I recv() the first page, it succeeds. However, the 2nd consecutive recv() will receive zero bytes, for which I really have no idea. As per HTTP 1.1 I have Connection: �Keep-Alive� in the http header I send.
If anyone is familar with this would you please take a look at the code and explain what was wrong with it?
here is the extracted socket-related code in a small test program :wall:
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <string>
#include <iostream>
using namespace std;
// ------------------------------------------------------
const short SOCKET_ERROR = -1;
const short RECV_BUFFER_SIZE = 20;
const short REQUEST_BUFFER_SIZE = 255;
int sock;
char recv_buf [RECV_BUFFER_SIZE + 1];
char req_buf [REQUEST_BUFFER_SIZE + 1];
const static char REQUEST_TEMPLATE [] =
{
"GET %s HTTP/1.1\r\n"
"Host: xxx.xxx.xxx\r\n" // should be replaced with a really host
"Connection: Keep-Alive\r\n"
"\r\n"
};
// ------------------------------------------------------
void create_socket ();
void download (const string& path, string& response);
// ------------------------------------------------------
int main (void)
{
string first_addr = "/~pdu/index.html"; // should be replaced with a really URL
string second_addr = "/~pdu/a.html"; // should be replaced with a really URL
string response;
create_socket ();
download (first_addr, response);
cout << response << endl << endl;
response = "";
download (second_addr, response);
if (response.size() > 0)
{
cout << response << endl;
}
else
{
cout << "### The 2nd recv() failed to receive any bytes from the socket!" << endl << endl;
}
close (sock);
return 0;
}
void create_socket ()
{
struct sockaddr_in addr;
// ------------------------------------------------------
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sock == SOCKET_ERROR)
{
perror ("Could not make a socket.\n");
exit (-1);
}
cout << ">>> Socket created!" << endl;
// ------------------------------------------------------
struct hostent* host_info = gethostbyname("cse.unl.edu");
cout << ">>> DNS done!" << endl;
long host_addr;
/* copy address into long */
memcpy(&host_addr, host_info->h_addr,
host_info->h_length);
/* fill address struct */
addr.sin_addr.s_addr = host_addr;
addr.sin_port = htons(80);
addr.sin_family = AF_INET;
// ------------------------------------------------------
if( connect(sock, (struct sockaddr*)(&addr),
sizeof(addr)) == SOCKET_ERROR )
{
perror("Could not connect to HTTP server.\n");
exit (-1);
}
cout << ">>> Connection established!" << endl;
}
void download (const string& path, string& response)
{
size_t nBytes = snprintf(
req_buf,
REQUEST_BUFFER_SIZE,
REQUEST_TEMPLATE,
path.c_str());
if (nBytes >= REQUEST_BUFFER_SIZE)
{
cerr << "Buffer is too small for making a request message" << endl;
exit (-1);
}
if (send(sock, req_buf, nBytes, 0) != nBytes)
{
perror("Could not send request to the HTTP server.\n");
exit (-1);
}
cout << ">>> Request sent! -> " << path << endl << req_buf << endl;
ssize_t size = 0;
while ((size = recv(sock, recv_buf,
RECV_BUFFER_SIZE, 0)) > 0)
{
recv_buf = '\0';
response.append(recv_buf);
}
cout << ">>> Response received!" << endl;
}