C - HTTP Socket Programming


 
Thread Tools Search this Thread
Top Forums Programming C - HTTP Socket Programming
# 15  
Old 04-15-2009
Quote:
Originally Posted by kev_1234
Well I am not really fussed about how much I get back host as long as I get back some info.Smilie
Could you rephrase that? I'm not sure what you were trying to say.
Quote:
1. Client sends a request to the Server for "GET /index.html HTTP/1.1\r\n\r\n".
Oh, you want to make a web server? The client needs to send() this information over the socket, see man 2 send.
Quote:
2. Server accepts the connection and then sends the requested material back to the client basically dumping the information of index.htmlo on the client.
This leaves out a whole bunch of steps, which may be why you're stymied.
  • Accept the connection
  • Read from it until \r\n\r\n -- recv() cares not about linefeeds, it just gives you chunks of data, so you may need to do a loop reading one character at a time in order to spot when the line ends.
  • Process the request -- you need to break "GET /index.html HTTP/1.1" into its component parts. You may be able to do this with sscanf():
    Code:
    char code[64], url[512], standard[64];
    sscanf(buf, "%s %s %s", code, url, standard);

    This is a fairly quick-and-dirty solution. A better way may be to use strtok().
  • Convert /index.html into /path/to/webroot/index.html -- standard C string functions should do here.
    Code:
    char filename[512];
    FILE *fp;
    strcpy(filename, "/path/to/webroot/");
    strcat(filename, webfile);

  • Open the given file, read from it, and send it to the socket
    Code:
    size_t sent;
    char buf[512];
    FILE *fp=fopen(filename, "r");
    if(fp == NULL)
    {
      fprintf(stderr, "Couldn't open %s\n", filename);
      return(1);
    }
    
    while( (sent=fread(buf, 512, 1 fp)) > 0)
    {
      send(sock, buf, sent, 0);
    }
    
    fclose(fp);

# 16  
Old 04-15-2009
Thanks again for your explanation I appreciate itSmilie

But I have sort of understood what you are trying to say....Smilie

First of all this code which you posted in your first post, would it be possible for you to explain me what its doing please?
Code:
echoServAddr.sin_family      = AF_INET;             /* Internet address family */ 
    {
      struct in_addr a;
      struct hostent *h=gethostbyname(servIP);
      if(h == NULL)
        DieWithError("Unknown host");

      memcpy(&a, h->h_addr_list[0], sizeof(a));
 
      servIP=inet_ntoa(a);
    }    
    echoServAddr.sin_addr.s_addr = inet_addr(servIP);   /* Server IP address */

Also just for beginning how can I send a simple GET HTTP request and get back the result........so that I can get an idea of how to implement it further....

Last edited by kev_1234; 04-15-2009 at 08:49 PM..
# 17  
Old 04-16-2009
Quote:
Originally Posted by kev_1234
But I have sort of understood what you are trying to say....Smilie
You have? Or do you mean you haven't? And I still don't understand what I asked about last time. I regret to say it, but I think the language barrier is making this extremely difficult...
Quote:
First of all this code which you posted in your first post, would it be possible for you to explain me what its doing please?
It uses gethostbyname() to convert the address given into something you can use to make sockets. See man gethostbyname and man inet_ntoa(a).
Quote:
Also just for beginning how can I send a simple GET HTTP request and get back the result........so that I can get an idea of how to implement it further....
See my last post to you for step-by-step details on this.
# 18  
Old 04-16-2009
Quote:
Originally Posted by Corona688
You have? Or do you mean you haven't? And I still don't understand what I asked about last time. I regret to say it, but I think the language barrier is making this extremely difficult...
Sorry Dude! About the language barrier.......SmilieDon't worry I am a English literate.....SmilieSmilie

Anyhow back to the topic yes I haven't understood what you posted earlier......please care to explain again......

As I am not sure where's what going into client and server.....may be I need to explore more about socket programming which I am researching.....Smilie

Quote:
It uses gethostbyname() to convert the address given into something you can use to make sockets. See man gethostbyname and man inet_ntoa(a).
Thanks for explaining this.

Quote:
See my last post to you for step-by-step details on this.
I shall look into it more.....
# 19  
Old 04-16-2009
Quote:
Originally Posted by kev_1234
Sorry, dude! About the language barrier -- don't worry, I am English literate.

Anyhow, back to the topic. Yes, I didn't understand what you posted earlier. Please explain further.
I'll explain in more detail how sockets are created and used.

There are lots and lots of kinds of sockets in UNIX, which is why the socket() call is so complex, but we're only interested in TCP sockets so we can disregard a lot of that.
  • Server
    • Create the socket:
      Code:
      servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

      It doesn't have any address or port at this point. It just exists, kind of blank.
    • Describe the address and port we want the socket to have, and bind it to it:
      Code:
          /* Construct local address structure */ 
          memset(&echoServAddr, 0, sizeof(echoServAddr));   /* Zero out structure */ 
          echoServAddr.sin_family = AF_INET;                /* Internet address family */ 
          echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ 
          echoServAddr.sin_port = htons(echoServPort);      /* Local port */ 
       
          /* Bind to the local address */ 
          if (bind(servSock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0) 
              DieWithError("bind() failed");

      This is also more complex than it needs to be since the bind() call can describe many different kinds of addresses. For TCP/IP, the family will always be AF_INET. INADDR_ANY is just the IP address 0.0.0.0; giving it this address tells the socket to respond on any IP addresses your machine offers. If we gave it the IP address of one particular interface, it would only respond on that interface. If we gave it an IP address the machine didn't have, it'd just fail to bind the socket. htonl() makes sure the bytes of the address are in the correct order. htons() does the same for the port.
    • Accept a connection on the socket:
      Code:
               /* Set the size of the in-out parameter */ 
              clntLen = sizeof(echoClntAddr); 
       
              /* Wait for a client to connect */ 
              if ((clntSock = accept(servSock, (struct sockaddr *) &echoClntAddr,  
                                     &clntLen)) < 0) 
                  DieWithError("accept() failed"); 
       
              /* clntSock is connected to a client! */ 
       
              printf("Handling client %s\n", inet_ntoa(echoClntAddr.sin_addr));

      The accept() call will wait until someone connects to the socket. When someone does, it gives you a new, seperate file handle you can send() and recv() with, and fills out a structure explaining where the connection came from, in this case, echoCIntAddr.
  • Client
    • The socket is created the same way.
    • But instead of bind(), we use connect():
      Code:
          /* Construct the server address structure */ 
          memset(&echoServAddr, 0, sizeof(echoServAddr));     /* Zero out structure */ 
          echoServAddr.sin_family      = AF_INET;             /* Internet address family */ 
          echoServAddr.sin_addr.s_addr = inet_addr(servIP);   /* Server IP address */ 
          echoServAddr.sin_port        = htons(echoServPort); /* Server port */ 
       
          /* Establish the connection to the echo server */ 
          if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0) 
              DieWithError("connect() failed");

      Note how instead of INADDR_ANY like the server, we give it the server's actual IP address to connect to.

      connect() doesn't create a new socket like accept() does, it converts the existing socket into one you can send() and recv() with.
# 20  
Old 04-16-2009
Quote:
Originally Posted by Corona688
I'll explain in more detail how sockets are created and used.

There are lots and lots of kinds of sockets in UNIX, which is why the socket() call is so complex, but we're only interested in TCP sockets so we can disregard a lot of that.
  • Server
    • Create the socket:
      Code:
      servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

      It doesn't have any address or port at this point. It just exists, kind of blank.
    • Describe the address and port we want the socket to have, and bind it to it:
      Code:
          /* Construct local address structure */ 
          memset(&echoServAddr, 0, sizeof(echoServAddr));   /* Zero out structure */ 
          echoServAddr.sin_family = AF_INET;                /* Internet address family */ 
          echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ 
          echoServAddr.sin_port = htons(echoServPort);      /* Local port */ 
       
          /* Bind to the local address */ 
          if (bind(servSock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0) 
              DieWithError("bind() failed");

      This is also more complex than it needs to be since the bind() call can describe many different kinds of addresses. For TCP/IP, the family will always be AF_INET. INADDR_ANY is just the IP address 0.0.0.0; giving it this address tells the socket to respond on any IP addresses your machine offers. If we gave it the IP address of one particular interface, it would only respond on that interface. If we gave it an IP address the machine didn't have, it'd just fail to bind the socket. htonl() makes sure the bytes of the address are in the correct order. htons() does the same for the port.
    • Accept a connection on the socket:
      Code:
               /* Set the size of the in-out parameter */ 
              clntLen = sizeof(echoClntAddr); 
       
              /* Wait for a client to connect */ 
              if ((clntSock = accept(servSock, (struct sockaddr *) &echoClntAddr,  
                                     &clntLen)) < 0) 
                  DieWithError("accept() failed"); 
       
              /* clntSock is connected to a client! */ 
       
              printf("Handling client %s\n", inet_ntoa(echoClntAddr.sin_addr));

      The accept() call will wait until someone connects to the socket. When someone does, it gives you a new, seperate file handle you can send() and recv() with, and fills out a structure explaining where the connection came from, in this case, echoCIntAddr.
  • Client
    • The socket is created the same way.
    • But instead of bind(), we use connect():
      Code:
          /* Construct the server address structure */ 
          memset(&echoServAddr, 0, sizeof(echoServAddr));     /* Zero out structure */ 
          echoServAddr.sin_family      = AF_INET;             /* Internet address family */ 
          echoServAddr.sin_addr.s_addr = inet_addr(servIP);   /* Server IP address */ 
          echoServAddr.sin_port        = htons(echoServPort); /* Server port */ 
       
          /* Establish the connection to the echo server */ 
          if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0) 
              DieWithError("connect() failed");

      Note how instead of INADDR_ANY like the server, we give it the server's actual IP address to connect to.

      connect() doesn't create a new socket like accept() does, it converts the existing socket into one you can send() and recv() with.
Once again thank you for your prolonged explanationSmilie.


Quote:
Sorry, dude! About the language barrier -- don't worry, I am English literate.

Anyhow, back to the topic. Yes, I didn't understand what you posted earlier. Please explain further.
Well I think this has become more of a English lesson than a learning exercise in 'socket-programming', as there was no need to point out how good or bad my English is or was. Also I have a habit of putting (.........) between comments when posting on a forum.

Perhaps I shall be more formal so that people are able to understand what I am typing Smilie

Last edited by kev_1234; 04-16-2009 at 01:24 PM..
# 21  
Old 04-16-2009
RightSmilie

After a bit of researching and editing, I have come up with this for my client.c:
Code:
#include <stdio.h>      /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
#include <arpa/inet.h>  /* for sockaddr_in and inet_addr() */
#include <stdlib.h>     /* for atoi() and exit() */
#include <string.h>     /* for memset() */
#include <unistd.h>     /* for close() */
#include <netdb.h>

#define RCVBUFSIZE 64   /* Size of receive buffer */
#define PORT 80
#define USERAGENT "HTMLGET 1.0"

void DieWithError(char *errorMessage);  /* Error handling function */

int main(int argc, char *argv[])
{
    int sock;                        /* Socket descriptor */
    struct sockaddr_in echoServAddr; /* Echo server address */
    unsigned short echoServPort;     /* Echo server port */
    char *servIP;                    /* Server IP address (dotted quad) */
    char *echoString;                /* String to send to echo server */
    char echoBuffer[RCVBUFSIZE];     /* Buffer for echo string */
    unsigned int echoStringLen;      /* Length of string to echo */
    int bytesRcvd, totalBytesRcvd;   /* Bytes read in single recv() 
                                        and total bytes read */
   
   
    if ((argc < 3) || (argc > 4))    /* Test for correct number of arguments */
    {
      
      fprintf(stderr, "Usage: %s <servername> <message> <Echo Port>\n",
               argv[0]);
       exit(1);
    }


    servIP = argv[1];             /* First arg: server IP address (dotted quad) */
    

    if (argc == 4)
        echoServPort = atoi(argv[3]); /* Use given port, if any */
    else
        echoServPort = 7;  /* 7 is the well-known port for the echo service */

    /* Create a reliable, stream socket using TCP */
    if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
        DieWithError("socket() failed");

    /* If connected then send the message */
    if ( connect(sock, (struct sockaddr*)&echoServAddr, sizeof(echoServAddr)) == 0)
    {    char s[200];
        FILE *fp = fdopen(sock, "r+");       /* convert into stream */

        fprintf(fp, argv[2]);                     /* send request */
        fprintf(fp, "\n\n");                 /* add some newlines */
        fflush(fp);                          /* ensure it got out */
        while ( fgets(s, sizeof(s), fp) != 0 )/* while not EOF ...*/
            fputs(s, stdout);                /*... print the data */
        fclose(fp);                           /* close the socket */
    }
    
    /* Construct the server address structure */
    memset(&echoServAddr, 0, sizeof(echoServAddr));     /* Zero out structure */
    echoServAddr.sin_family      = AF_INET;             /* Internet address family */     
    echoServAddr.sin_addr.s_addr = inet_addr(servIP);   /* Server IP address */
    echoServAddr.sin_port        = htons(echoServPort); /* Server port */

    /* Establish the connection to the echo server */ 
    if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0) 
        DieWithError("connect() failed"); 
    echoStringLen = strlen(echoString);          /* Determine input length */ 
 
    /* Send the string to the server */ 
    if (send(sock, echoString, echoStringLen, 0) != echoStringLen) 
        DieWithError("send() sent a different number of bytes than expected"); 
 
    /* Receive the same string back from the server */ 
    totalBytesRcvd = 0; 
    printf("Received: ");                /* Setup to print the echoed string */ 
    while (totalBytesRcvd < echoStringLen) 
    { 
        /* Receive up to the buffer size (minus 1 to leave space for 
           a null terminator) bytes from the sender */ 
        if ((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <= 0) 
            DieWithError("recv() failed or connection closed prematurely"); 
        totalBytesRcvd += bytesRcvd;   /* Keep tally of total bytes */ 
        echoBuffer[bytesRcvd] = '\0';  /* Terminate the string! */ 
        printf("%s", echoBuffer);      /* Print the echo buffer */ 
    } 
 
    printf("\n");    /* Print a final linefeed */ 
 
    close(sock); 
    exit(0); 
}//-- end main --// 
 
 
 
// 
//// 
// 
void DieWithError(char *errorMessage) 
{ 
    perror(errorMessage); 
    exit(1); 
}

But..........
It is complaining about line 53.
This is the warning it gives me
Quote:
client.c: In function ‘main’:
client.c:53: warning: format not a string literal and no format arguments
Line 53 is
Code:
fprintf(fp, argv[2]);                     /* send request */

Could you please check!!!

Thanks

Last edited by kev_1234; 04-16-2009 at 10:05 PM..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Programming

socket programming

how to include socket.h in visual studio 2005.. (2 Replies)
Discussion started by: asd123
2 Replies

2. Shell Programming and Scripting

sending http url through http socket programming..

hi am senthil am developing a software to send and receive SMS using HTTP connection first of all am forming a URL and sending that URL to a remote server using my Client Program i send that url through Socket(using Send() Function) if i send more than one URL one by one using the same... (4 Replies)
Discussion started by: senkerth
4 Replies

3. Programming

sending http url through http socket programming..

hi am senthil am developing a software to send and receive SMS using HTTP connection first of all am forming a URL and sending that URL to a remote server using my Client Program i send that url through Socket(using Send() Function) if i send more than one URL one by one using the same... (0 Replies)
Discussion started by: senkerth
0 Replies

4. Programming

unable to get end of file while reading HTTP data from socket

I am trying to read HTTP data from a socket. However, for the final set of data being read using read(), read blocks and the control doesnt come back for further processing. I tried using select, but it didn't work... Any help would be greatly acknowledged.:) (2 Replies)
Discussion started by: Harish.joshi
2 Replies

5. IP Networking

socket programming

Hello Everyone Iam working on tcp/ip programming.with some time interval server has to send data.client has to close the connection and to open the connection between the time interval.this is the scenario when iam closing the connection in client side the connection terminates.how to... (1 Reply)
Discussion started by: sureshvaikuntam
1 Replies

6. Programming

HTTP Keep-Alive socket problem

Hello everyone, I am a newbie in UNIX/Linux socket programming. This is a class project that I had trouble with. ================================================== I was trying to make “Keep-Alive” HTTP connections to the server in a tiny web crawler project. Here is the problem: when I tried... (0 Replies)
Discussion started by: imdupeng
0 Replies

7. Programming

Socket programming

Hello!:) I'm trying to do some socket programming based on the following situation: I have a directory service named Casino that will hold all the information regarding the gamers that will try to connect to it in order to play a game(for example (Blackjack).Once they make the login they are... (4 Replies)
Discussion started by: maracumbigo
4 Replies

8. IP Networking

socket programming

my system is a stand alone system... i want to try doing socket porgramming..ihave heard that this is usually done during testing... how can i do that....? (6 Replies)
Discussion started by: damn_bkb
6 Replies

9. Programming

Socket Programming socket

Hello, I actually try to make client-server program. I'm using SCO OpenServer Release 5.0.0 and when I try to compile my code (by TELNET) I've got this error : I'm just using this simple code : and I get the same error if I use : If someone can help me, Thanks (2 Replies)
Discussion started by: soshell
2 Replies

10. Programming

Socket Programming

Dear Reader, Is there any way to check up socket status other than 'netstatus ' Thanks in advance, (1 Reply)
Discussion started by: joseph_shibu
1 Replies
Login or Register to Ask a Question