11 Replies - 3205 Views - Last Post: 27 April 2009 - 01:17 PM Rate Topic: -----

#1 kevin_911  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 127
  • Joined: 02-April 09

TCP/IP in C programming

Posted 02 April 2009 - 02:24 PM

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 want my Client and Server files be able to do is bascially Punch in a request to the server for

Quote

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......

I know I require

int GET_MOTOR_STATUS();
void SET_MOTOR_STATUS(int i);
int READ_TEMP(int n);



So how could I begin

Thanks

client.c
#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);
}




server.c

#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 */
}




Is This A Good Question/Topic? 0
  • +

Replies To: TCP/IP in C programming

#2 no2pencil  Icon User is offline

  • Admiral Fancy Pants
  • member icon

Reputation: 5413
  • View blog
  • Posts: 27,429
  • Joined: 10-May 07

Re: TCP/IP in C programming

Posted 02 April 2009 - 08:59 PM

View Postkevin_911, on 2 Apr, 2009 - 03:24 PM, said:

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

You're reading The Pocket Guide to TCP/IP Sockets in C by Michael Donahoo & Kenneth Calvert, aren't you?
Was This Post Helpful? 0
  • +
  • -

#3 kevin_911  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 127
  • Joined: 02-April 09

Re: TCP/IP in C programming

Posted 03 April 2009 - 10:32 AM

View Postno2pencil, on 2 Apr, 2009 - 07:59 PM, said:

View Postkevin_911, on 2 Apr, 2009 - 03:24 PM, said:

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

You're reading The Pocket Guide to TCP/IP Sockets in C by Michael Donahoo & Kenneth Calvert, aren't you?


Yes mate! :)

Anybody with few ideas as how I could achieve in my first post.....

In short basically call for a test.HTML file and in return get back its contents.
Was This Post Helpful? 0
  • +
  • -

#4 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6111
  • View blog
  • Posts: 23,671
  • Joined: 23-August 08

Re: TCP/IP in C programming

Posted 03 April 2009 - 11:23 AM

Connect to remote machine.
Send "GET /test.html HTTP/1.0\r\n\r\n" via the socket to the remote machine.
Receive bytes until 0 is returned.
Was This Post Helpful? 0
  • +
  • -

#5 kevin_911  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 127
  • Joined: 02-April 09

Re: TCP/IP in C programming

Posted 03 April 2009 - 02:01 PM

View PostJackOfAllTrades, on 3 Apr, 2009 - 10:23 AM, said:

Connect to remote machine.
Send "GET /test.html HTTP/1.0\r\n\r\n" via the socket to the remote machine.
Receive bytes until 0 is returned.


Sir! could you please explain in a bit more detail please as I am begginer :unsure:

Do I need to change anything in my code......
Was This Post Helpful? 0
  • +
  • -

#6 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6111
  • View blog
  • Posts: 23,671
  • Joined: 23-August 08

Re: TCP/IP in C programming

Posted 03 April 2009 - 02:58 PM

This is off the top of my head, but client code demonstrates what you need to do there. If you put in 74.125.91.99 and a port of 80, you'll connect to the Google homepage and download the raw HTML from there and print it out. I'll leave it as an exercise for you to figure out where it goes. It shouldn't be hard to do that.

/* Send the string to the server */
const char *getTestRequest = "GET / HTTP/1.0\r\n\r\n";
size_t requestLen = strlen(getTestRequest);
if (send(sock, getTestRequest, requestLen, 0) != requestLen)
    DieWithError("send() sent a different number of bytes than expected");

printf("Received: ");
char receivedData[RCVBUFSIZE] = { 0 };

/* Start first retrieval */
bytesRcvd = recv(sock, receivedData, RCVBUFSIZE - 1, 0);
if (bytesRcvd <= 0)
    DieWithError("recv() failed or connection closed prematurely");

/* OK, retrieve more data until the remote server
    returns 0, which means they're done, or <0, which
    means there was a failure */
while (bytesRcvd > 0)
{
    /* Receive up to the buffer size (minus 1 to leave space for
        a null terminator) bytes from the sender */
    receivedData[bytesRcvd] = '\0';  /* Terminate the string! */
    printf("%s", receivedData);

    bytesRcvd = recv(sock, receivedData, RCVBUFSIZE - 1, 0);
}
if (bytesRcvd < 0)
{
    /* There was an error */
    DieWithError("recv() failed or connection closed prematurely");
}


Was This Post Helpful? 0
  • +
  • -

#7 kevin_911  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 127
  • Joined: 02-April 09

Re: TCP/IP in C programming

Posted 03 April 2009 - 03:11 PM

View PostJackOfAllTrades, on 3 Apr, 2009 - 01:58 PM, said:

This is off the top of my head, but client code demonstrates what you need to do there. If you put in 74.125.91.99 and a port of 80, you'll connect to the Google homepage and download the raw HTML from there and print it out. I'll leave it as an exercise for you to figure out where it goes. It shouldn't be hard to do that.


Thanks bro! I like exercises! :D

I'll give it a go! :^:
Was This Post Helpful? 0
  • +
  • -

#8 kevin_911  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 127
  • Joined: 02-April 09

Re: TCP/IP in C programming

Posted 06 April 2009 - 08:12 AM

Hello sorry didn't get back to you!

Any way's I adjusted the Client socket to this:
#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 */

	const char *getTestRequest = "GET / HTTP/1.0\r\n\r\n";
	size_t requestLen = strlen(getTestRequest);


	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 */

	printf("Received: ");				/* Setup to print the echoed string */

	char receivedData[RCVBUFSIZE] = { 0 };

   /* Start first retrieval */		

		bytesRcvd = recv(sock, receivedData, RCVBUFSIZE - 1, 0);
	if (bytesRcvd <= 0)
		DieWithError("recv() failed or connection closed prematurely");

	/* OK, retrieve more data until the remote server
		returns 0, which means they're done, or <0, which
		means there was a failure */
	while (bytesRcvd > 0)
	{
		/* Receive up to the buffer size (minus 1 to leave space for
		a null terminator) bytes from the sender */
		receivedData[bytesRcvd] = '\0';  /* Terminate the string! */
		printf("%s", receivedData);

		bytesRcvd = recv(sock, receivedData, RCVBUFSIZE - 1, 0);
	}
	if (bytesRcvd < 0)
	{
		/* There was an error */
		DieWithError("recv() failed or connection closed prematurely");
	}


	printf("\n");	/* Print a final linefeed */



	close(sock);

	exit(0);

}//-- end main --//







//

////

//

void DieWithError(char *errorMessage)

{

	perror(errorMessage);

	exit(1);

}



Does it look right? also you said connect to port 80 and I.P 74.125.91.99 it still didnt work?

One more thing do I need to make any changes to the server side???

N.B:Apologies for asking dump questions!

This post has been edited by kevin_911: 06 April 2009 - 08:14 AM

Was This Post Helpful? 0
  • +
  • -

#9 kevin_911  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 127
  • Joined: 02-April 09

Re: TCP/IP in C programming

Posted 07 April 2009 - 04:25 AM

"JackOfAllTrades" did you have a look at my last post?
Was This Post Helpful? 0
  • +
  • -

#10 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6111
  • View blog
  • Posts: 23,671
  • Joined: 23-August 08

Re: TCP/IP in C programming

Posted 07 April 2009 - 06:02 AM

All I did was show you how to read data from a socket by connecting to a web server, in this case Google, and downloading the data.

Have you checked out Beej's Guide?
Was This Post Helpful? 0
  • +
  • -

#11 kevin_911  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 127
  • Joined: 02-April 09

Re: TCP/IP in C programming

Posted 07 April 2009 - 08:55 AM

View PostJackOfAllTrades, on 7 Apr, 2009 - 05:02 AM, said:

All I did was show you how to read data from a socket by connecting to a web server, in this case Google, and downloading the data.

Have you checked out Beej's Guide?


yeah petty half of the links in the guide doesn't even work :ohno:
Was This Post Helpful? 0
  • +
  • -

#12 kevin_911  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 127
  • Joined: 02-April 09

Re: TCP/IP in C programming

Posted 27 April 2009 - 01:17 PM

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 /test.html /HTTP1.0",echoBuffer,18)==0){
			if( !(inputFilePtr = fopen("test.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 /test.HTML /HTTP1.0" 1500



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

Now, I have four test.html files with this as its content:
test2.html

Quote

temp=1


and then on the next test3.html with this as its content :

Quote

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
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1