I am begginer in C so please be easy on me.....:-)

Anyways....my query is I have a server and a Client program written in C(attached below) for test in UNIX/LINUX in which the client sends a request to the server and the server then sends back the request to the client.

What I am looking for is bascially Punch in a request to the server for

GET/test.html /HTTP1.0

and in return get the contents of the test.html file which would be something along the lines on motor status(on or off) and the value of 4 temperature sensors......

So any ideas then please let me know

Thanks

Attachments
#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() */

#define RCVBUFSIZE 64   /* Size of receive buffer */

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 <Server IP> <Echo Word> [<Echo Port>]\n",
               argv[0]);
       exit(1);
    }

    servIP = argv[1];             /* First arg: server IP address (dotted quad) */
    echoString = argv[2];         /* Second arg: string to echo */

    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");

    /* 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);
}
#include <stdio.h>      /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket(), bind(), and connect() */
#include <arpa/inet.h>  /* for sockaddr_in and inet_ntoa() */
#include <stdlib.h>     /* for atoi() and exit() */
#include <string.h>     /* for memset() */
#include <unistd.h>     /* for close() */

#define RCVBUFSIZE 64   /* Size of receive buffer */
#define MAXPENDING 5    /* Maximum outstanding connection requests */

void DieWithError(char *errorMessage);  /* Error handling function */
void HandleTCPClient(int clntSocket);   /* TCP client handling function */

int main(int argc, char *argv[])
{
    int servSock;                    /* Socket descriptor for server */
    int clntSock;                    /* Socket descriptor for client */
    struct sockaddr_in echoServAddr; /* Local address */
    struct sockaddr_in echoClntAddr; /* Client address */
    unsigned short echoServPort;     /* Server port */
    unsigned int clntLen;            /* Length of client address data structure */

    if (argc != 2)     /* Test for correct number of arguments */
    {
        fprintf(stderr, "Usage:  %s <Server Port>\n", argv[0]);
        exit(1);
    }

    echoServPort = atoi(argv[1]);  /* First arg:  local port */

    /* Create socket for incoming connections */
    if ((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
        DieWithError("socket() failed");
      
    /* 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");

    /* Mark the socket so it will listen for incoming connections */
    if (listen(servSock, MAXPENDING) < 0)
        DieWithError("listen() failed");

    for (;;) /* Run forever */
    {
        /* 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));

        HandleTCPClient(clntSock);
    }
    /* NOT REACHED */
}//-- end main --//



//
////
//
void DieWithError(char *errorMessage)
{
    perror(errorMessage);
    exit(1);
}



//
////
//
void HandleTCPClient(int clntSocket)
{
    char echoBuffer[RCVBUFSIZE];        /* Buffer for echo string */
    int recvMsgSize;                    /* Size of received message */

    /* Receive message from client */
    if ((recvMsgSize = recv(clntSocket, echoBuffer, RCVBUFSIZE, 0)) < 0)
        DieWithError("recv() failed");

    /* got incoming request from client in the echobuffer */
    recvMsgSize = sprintf(echoBuffer,
                          "MOTOR=0,TEMPS are 3A,42,FA,99");//reply! 

    /* Send received string and receive again until end of transmission */
    while (recvMsgSize > 0)      /* zero indicates end of transmission */
    {
        /* Echo message back to client */
        if (send(clntSocket, echoBuffer, recvMsgSize, 0) != recvMsgSize)
            DieWithError("send() failed");

        /* See if there is more data to receive */
        if ((recvMsgSize = recv(clntSocket, echoBuffer, RCVBUFSIZE, 0)) < 0)
            DieWithError("recv() failed");
    }

    close(clntSocket);    /* Close client socket */
}

i haven't tested it, but it looks right.

so, what's your question? didnt the site you downloaded the programs from give you some instructions?

i haven't tested it, but it looks right.

so, what's your question? didnt the site you downloaded the programs from give you some instructions?

Basically I send a request by entering the following to the server

GET/DATA.HTML /HTTP1.0

and get back the contents of DATA.HTML in the client side.....

have you even tried running it?

you run the server on one computer. run the client on another.

specify the port that the server will use by passing the port number as an argument to the executable. see code for example

if (argc != 2)     /* Test for correct number of arguments */
    {
        fprintf(stderr, "Usage:  %s <Server Port>\n", argv[0]);
        exit(1);
    }

    echoServPort = atoi(argv[1]);  /* First arg:  local port */

don't use a reserved port number. pick something greater than 1000 and you should be safe

for the client, send the Server IP, Command, and Port # as arguments to the executable. see the code for example.

if ((argc < 3) || (argc > 4))    /* Test for correct number of arguments */
    {
       fprintf(stderr, "Usage: %s <Server IP> <Echo Word> [<Echo Port>]\n",
               argv[0]);
       exit(1);
    }

Oh yes I've tested the scripts on Ubuntu..........

Basically opened two terminal windows.......

One acting as a Server and one as a Client........

After I setup the Server like

./S 1500

and then the server basically waits for the client to send the request.

then on the other window....

./C 127.0.0.1 Hello 1500

On the server side it says handling 127.0.0.1

and on the client side it says MOTOR=0,TEMPS are 3A,42,FA,99

whereas I want to use the same concept to get back the values on the HTML files something like this

<html>
<body>
Hello
</body>
</html>

sounds like the program is working correctly.

review the file that you think is being sent, versus the file that is actually being sent.

i believe there you will find the source of your confusion.

oh, i just re-read your last post.

the problem is not with TCP/IP.

the problem is that you need to take the values that you get from the server, and rewrite them to a file with HTML tags.

maaann....

if you can write a server and a client, what you're asking is CHILDS PLAY... ;)

i mean, really...

"fopen"
a bunch of "fprintf"
"fclose"

and you're done.

oh, i just re-read your last post.

the problem is not with TCP/IP.

the problem is that you need to take the values that you get from the server, and rewrite them to a file with HTML tags.

maaann....

if you can write a server and a client, what you're asking is CHILDS PLAY... ;)

i mean, really...

"fopen"
a bunch of "fprintf"
"fclose"

and you're done.

Cheers man for the advice! well I didn't write the server and client....Got it from a reference book as I am trying to understand Unix networking programming.....

the best way to understand is to spend a lot of time making mistakes.

just start hacking away at a solution. understanding will come later. meanwhile, figure out how to use those three commands i mentioned (any online reference) and that's about all you need.

Right time for an update!:)

I have been digging about with code and have been able to do most of the stuff but few couple of issues.....

This is the code I implemented into my S.c

if ((recvMsgSize = recv(clntSocket, echoBuffer, RCVBUFSIZE, 0)) > 0)
    {
        puts(echoBuffer);
        if ( strncmp("GET /DATA.HTML /HTTP1.0",echoBuffer,18)==0){
            if( !(inputFilePtr = fopen("DATA.HTML", "r"))){
                puts("ERROR: file open error");close(clntSocket);exit(1);
            }
            i=0;
            do{
                echoBuffer[i++]=fgetc(inputFilePtr);
            }while (!feof(inputFilePtr));
            echoBuffer[i]='\0'; // i holds length
            recvMsgSize=i;
            printf("\nGot %d chars from file\n",i);

        }
        else puts("bad input received\n");
    }   
    else{
         close(clntSocket);
         DieWithError("recv() failed");
     }

So once I have the Server running.......

and if i type in this from my client side

./C 127.0.0.1 "GET /DATA.HTML /HTTP1.0" 1500

I am able to get the contents of the file back from the server.

Now, I have four DATA.HTML files with this as its content:
DATA2.HTML

temp=1

and then on the next DATA3.HTML with this as its content :

temp=2

...etc......

So therefore I am not able to figure it out as how I can further inplement the code so that if I put this as my request

./C 127.0.0.1 "GET /DATA.HTML?temp=1 /HTTP1.0" 1500

I should then be able to get back the contents of DATA2.HTML
file which has temp=2 as its content......?????

Please advice

Edited 3 Years Ago by mike_2000_17: Fixed formatting

a few things here, that i think are confusing:

the string you are sending, "GET /DATA.HTML /HTTP1.0", is kind of meaningless. by that i mean there is nothing in this string that affects the behavior of the server. the whole concept of "GET" is that it's a command that tells the server what to do. other commands would be "PUT" or "DEL(ETE)" or "CD" or "DIR" or "QUIT". likewise your "DATA.HTML" means this should also be parsed so that you choose one file from one or more possible files in the working directory.

another thing thats bothering me somewhat is the ubiquitous use of the variable "echoBuffer" for both sending and receiving. i suggest that you change your Server code for the "HandleTCPclient" function to use the concept of send and receive, and forget about this 'echo':

void HandleTCPClient(int clntSocket)
{
    char recvBuffer[RCVBUFSIZE];        /* Buffer for recv string */
    char sendBuffer[SNDBUFSIZE];        /* Buffer for send string */
    int recvMsgSize;                    /* Size of receive message */
    int sendMsgSize;                    /* Size of send message */

    /* Receive message from client */
    if ((recvMsgSize = recv(clntSocket, recvBuffer, RCVBUFSIZE, 0)) < 0)
        DieWithError("recv() failed");
        
    /* incoming request from client is in the recvBuffer */
    /* message can be parsed as necessary */
    printf("  received client message: %s\n",recvBuffer);
    
    /* put outgoing message from server in the sendBuffer */   
    sprintf(sendBuffer,"MOTOR=0,TEMPS are 3A,42,FA,99");   //reply! 
    sendMsgSize = strlen(sendBuffer);

    /* Send message until transmission completed*/
    while (recvMsgSize > 0)      /* zero indicates end of transmission */
    {
        if (send(clntSocket, sendBuffer, sendMsgSize, 0) != sendMsgSize)
            DieWithError("send() failed");
  
        /* See if there is more data to receive */
        if ((recvMsgSize = recv(clntSocket, recvBuffer, RCVBUFSIZE, 0)) < 0)
            DieWithError("recv() failed");
    }
    close(clntSocket);    /* Close client socket */
}

look at this code now, and understand whats going on here: the server gets a request from the client in the "recv" buffer. at which point the server would normally parse the request and decide what to send via the "send" buffer.

so far, the only thing you are doing is sending a line of text about the MOTOR TEMPS.... it's doing exactly what you are telling it to do.

but since you want the server to read a file and send the contents of the file back to the client, you'll have to change the HandleTCPClient function in the server to read contents of the file, and send those contents back to the client instead of just the hardcoded line.

furthermore, if you're reading out an entire file, you would not have the client print all of the file's information to the terminal... you would have the client take the information received from the server and write it to another file on the client's end.

now, implement this into the new "HandleTCPClient" function that i provided, above. you can easily read and write one line at a time using fgets() and fprintf(). the preferred method would be to read and write large blocks of data using fread() and fwrite().

the best way to test this is to open two separate terminal windows, each one in a different directory.

.

This article has been dead for over six months. Start a new discussion instead.