FREE tutorial,solution,RSS Feeds on Operating Systems, Programming, Web Development, Applications, Databases, Networking, Hardware, Security, SEO Free Expertsforge Membership
Become a Moderator
Submit Article to Expertsforge.com Submit Article My Expertsforge
 
RSS Feeds, Help Help RSS Feeds
bannertop
div
 

C Tutorial: Socket Programming in C using TCP with Code

by: jawahar, 10/4/2005 1:13:31 AM, Views: 6901
 
To compile :

      * linux : gcc -Wall -o foo foo.c
      * solaris : gcc -Wall -o foo foo.c -lsocket -lnsl

1. TCP

      * TCP server : simple TCP server that prints received messages.
         source : tcpServer.c
         usage : ./tcpServer
      * TCP client : simple TCP client that sends data to server.
         source : tcpClient.c
         usage : ./tcpClient server data1 ... dataN


/*********************** tcpserver.c ***********************/

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h> /* close */


#define SUCCESS 0
#define ERROR    1

#define END_LINE 0x0
#define SERVER_PORT 1500
#define MAX_MSG 100

/* function readline */
int read_line();

int main (int argc, char *argv[]) {
   
   int sd, newSd, cliLen;

   struct sockaddr_in cliAddr, servAddr;
   char line[MAX_MSG];


   /* create socket */
   sd = socket(AF_INET, SOCK_STREAM, 0);
    if(sd<0) {
      perror("cannot open socket ");
      return ERROR;
   }
   
   /* bind server port */
   servAddr.sin_family = AF_INET;
   servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
   servAddr.sin_port = htons(SERVER_PORT);
   
   if(bind(sd, (struct sockaddr *) &servAddr, sizeof(servAddr))<0) {
      perror("cannot bind port ");
      return ERROR;
   }

   listen(sd,5);
   
   while(1) {

      printf("%s: waiting for data on port TCP %u\n",argv[0],SERVER_PORT);

      cliLen = sizeof(cliAddr);
      newSd = accept(sd, (struct sockaddr *) &cliAddr, &cliLen);
      if(newSd<0) {
         perror("cannot accept connection ");
         return ERROR;
      }
      
      /* init line */
      memset(line,0x0,MAX_MSG);
      
      /* receive segments */
      while(read_line(newSd,line)!=ERROR) {
         
         printf("%s: received from %s:TCP%d : %s\n", argv[0],
          inet_ntoa(cliAddr.sin_addr),
          ntohs(cliAddr.sin_port), line);
         /* init line */
         memset(line,0x0,MAX_MSG);
         
      } /* while(read_line) */
      
   } /* while (1) */

}


/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING          */
/* this function is experimental.. I don't know yet if it works   */
/* correctly or not. Use Steven's readline() function to have      */
/* something robust.                                                                   */
/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING          */

/* rcv_line is my function readline(). Data is read from the socket
when */
/* needed, but not byte after bytes. All the received data is read.   
    */
/* This means only one call to recv(), instead of one call for         
    */
/* each received byte.                                                                     
    */
/* You can set END_CHAR to whatever means endofline for you. (0x0A is
\n)*/
/* read_lin returns the number of bytes returned in line_to_return   
    */
int read_line(int newSd, char *line_to_return) {
   
   static int rcv_ptr=0;
   static char rcv_msg[MAX_MSG];
   static int n;
   int offset;

   offset=0;

   while(1) {
      if(rcv_ptr==0) {
         /* read data from socket */
         memset(rcv_msg,0x0,MAX_MSG); /* init buffer */
         n = recv(newSd, rcv_msg, MAX_MSG, 0); /* wait for data */
         if (n<0) {
   perror(" cannot receive data ");
   return ERROR;
         } else if (n==0) {
   printf(" connection closed by client\n");
   close(newSd);
   return ERROR;
         }
      }
   
      /* if new data read on socket */
      /* OR */
      /* if another line is still in buffer */

      /* copy line into 'line_to_return' */
      while(*(rcv_msg+rcv_ptr)!=END_LINE && rcv_ptr<n) {
         memcpy(line_to_return+offset,rcv_msg+rcv_ptr,1);
         offset++;
         rcv_ptr++;
      }
      
      /* end of line + end of buffer => return line */
      if(rcv_ptr==n-1) {
         /* set last byte to END_LINE */
         *(line_to_return+offset)=END_LINE;
         rcv_ptr=0;
         return ++offset;
      }
      
      /* end of line but still some data in buffer => return line */
      if(rcv_ptr <n-1) {
         /* set last byte to END_LINE */
         *(line_to_return+offset)=END_LINE;
         rcv_ptr++;
         return ++offset;
      }

      /* end of buffer but line is not ended => */
      /*   wait for more data to arrive on socket */
      if(rcv_ptr == n) {
         rcv_ptr = 0;
      }
      
   } /* while */
}


/*********************** tcpclient.c ***********************/


/* tcpClient.c */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h> /* close */

#define SERVER_PORT 1500
#define MAX_MSG 100

int main (int argc, char *argv[]) {

   int sd, rc, i;
   struct sockaddr_in localAddr, servAddr;
   struct hostent *h;
   
   if(argc < 3) {
      printf("usage: %s <server> <data1> <data2> ... <dataN>\n",argv[0]);
      exit(1);
   }

   h = gethostbyname(argv[1]);
   if(h==NULL) {
      printf("%s: unknown host '%s'\n",argv[0],argv[1]);
      exit(1);
   }

   servAddr.sin_family = h->h_addrtype;
   memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0],
h->h_length);
   servAddr.sin_port = htons(SERVER_PORT);

   /* create socket */
   sd = socket(AF_INET, SOCK_STREAM, 0);
   if(sd<0) {
      perror("cannot open socket ");
      exit(1);
   }

   /* bind any port number */
   localAddr.sin_family = AF_INET;
   localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
   localAddr.sin_port = htons(0);
   
   rc = bind(sd, (struct sockaddr *) &localAddr, sizeof(localAddr));
   if(rc<0) {
      printf("%s: cannot bind port TCP %u\n",argv[0],SERVER_PORT);
      perror("error ");
      exit(1);
   }
            
   /* connect to server */
   rc = connect(sd, (struct sockaddr *) &servAddr, sizeof(servAddr));
   if(rc<0) {
      perror("cannot connect ");
      exit(1);
   }

   for(i=2;i<argc;i++) {
      
      rc = send(sd, argv[i], strlen(argv[i]) + 1, 0);
      
      if(rc<0) {
         perror("cannot send data ");
         close(sd);
         exit(1);
      
      }

      printf("%s: data%u sent (%s)\n",argv[0],i-1,argv[i]);

   
   }

return 0;
   
}
Next Steps:
Add this Tutorial to:
Rating Booth
Avg Visitor Rating: Average Visitor Rating is 3.5 out of 5
Number of Ratings : 6 Votes
Rate:
Signup / Login To View the Solution or Provide Comments
Post Comment/Solution
Comment:*
     
  Use : [bold] for <b>; [/bold] for </b>; [italic] for <i>; [/italic] for </i>; [code] & [/code] for code
 
Categories
sep
arrow
sep
arrow
sep
arrow
sep
arrow
sep
arrow
sep
arrow
sep
arrow
sep
arrow
sep
arrow
sep
arrow
sep
arrow
sep
Get Rid of Spyware with Anti Spyware Software
Options
»  Submit a Tutorial
» Ask a Question
» Add to KB
» View all your Q's
C RSS Feed
aachi_win
Most Popular Tutorial
1.Socket Programming i...
2.Socket Programming i...
3.Socket Programming i...
Most Popular Solution
Top Rated
1.Socket Programming i...
2.Socket Programming i...
Top Rankers
Overall
sep
1. jawahar150
sep

Yearly - 2008
sep
Expertsforge Sponsors
1. Tech News
2. Wii Reviews
bnrtop