I have some experience with client-server codes. TCP and udp client. I want to know how a stream socket works with HTTP.

This client is for a server-client code where the greatest common divisor is calculated and displayed.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <time.h>

#define MAX_BUFFER_LENGTH 100

int main(int argc, char *argv[])
{
    int sockfd;
    struct sockaddr_in their_addr; // connector's address information
    struct hostent *he;
    int numbytes;
    int serverPort;
    int a = 0;
    int b = 0;
    struct timespec time_a, time_b;

    printf("TCP client example \n\n");

    if (argc != 5) {
        fprintf(stderr,"Usage: tcpClient serverName serverPort int1 int2\n");
        exit(1);
    }

    serverPort = atoi(argv[2]);
    a = atoi(argv[3]);
    b = atoi(argv[4]);    

    //Resolv hostname to IP Address
    if ((he=gethostbyname(argv[1])) == NULL) {  // get the host info
        herror("gethostbyname");
        exit(1);
    }

    /* ******************************************************************
   Create socket
    ******************************************************************* */
    clock_gettime(CLOCK_REALTIME, &time_a);

    sockfd = socket(PF_INET,SOCK_STREAM,0);


    //setup transport address
    their_addr.sin_family = AF_INET;     
    their_addr.sin_port = htons(serverPort);
    their_addr.sin_addr = *((struct in_addr *)he->h_addr);
    memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero);


    /* ******************************************************************
   Binding
    ******************************************************************* */
    connect(sockfd,(struct sockaddr*)&their_addr, sizeof(their_addr));


    printf("Connection established \n");
    unsigned char buffer[4];

    packData(&buffer, a, b);
    printf("Data packed \n");
    /* ******************************************************************
     Send data
    ******************************************************************* */
    send(sockfd,buffer,sizeof(buffer),0);
  printf("Data Sent \n");
    printf("A: %d and B: %d. \n", a,b );

    /* ******************************************************************
    Close socket
    ******************************************************************* */
    close(sockfd);

    clock_gettime(CLOCK_REALTIME, &time_b);

    double diff = (time_b.tv_sec - time_a.tv_sec) + ((time_b.tv_nsec - time_a.tv_nsec)/1E9);
    printf("Client needed %lf sec.\n\n", diff);

    return 0;
}

int packData(unsigned char *buffer, unsigned int a, unsigned int b) {
    /* ******************************************************************
     pack data
    ******************************************************************* */
    buffer[0]=a>>8;
    buffer[1]=a;
    buffer[2]=b>>8;
    buffer[3]=b;

}

That it works with netcat, for instance. How do I rewrite the code to make it work with HTTP ? I been trying to figure it out, but nothing so far. It should only be some minor changes.

You don't really need to re-write the code so it works with HTTP, HTTP uses TCP/IP sockets. HTTP is from the application layer of the protocol stack and TCP from the Transport layer and IP from the Internet layer; respectively layers 4,3 and 2 of the communication stack. That is HTTP defines the data that should be sent to a webserver using a TCP/IP socket.

Generally most webservers (certainly all those publically accessable on the internet) use port 80, this port is reserved for that purpose.

All you have to do is send a valid command on the right port to the right server, for example

GET /index.php HTTP/1.1
Host: www.daniweb.com

Would retrieve the main index page from DaniWeb. Not that every line ends in a carridge-return, new-line pair '\r\n' in C parlance and that the request must end with a blank line (Which is not showing up even though I have marked it as code).

The frist line is the command, subsequent lines are headers and the blank line finishes the command. you will get a result a bit like

HTTP/1.1 200 OK
Date: Mon, 23 May 2014 17:38:34 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
Last-Modified: Wed, 10 May 2014 17:11:55 GMT
ETag: "3f80f-1b6-3e1cb03b"
Content-Type: text/html; charset=UTF-8
Content-Length: 131
Accept-Ranges: bytes
Connection: close

<html>
<head>
  <title>DaniWeb blah blah blah</title>
</head>
<body>
  all the stuff that makes up DaniWeb
</body>
</html>

The first line is the result, again followed by headers terminated with a blank line and then the data for the requested file.

The wikipedia page on HTTP is a reasonable place to start when working this out.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.