Sunday, August 14, 2011

Socket - UDP Datagram Server sample c code

Now you are equipped well enough to write a UDP datagram client and server program. In this section, you'll begin with a datagram server example (remember from my first post in this series, where you saw an example). This program took a strftime(3) format string as input and returned the formatted date and time string as a response. You are going to write a datagram server in this post, which will stand by itself, accept format strings as input datagrams. After the server formats a date string using the strftime(3) function, it will send the result back to the client program in another datagram as shown in Listing below,

 /* dgramsrvr.c:
  *
  * Example datagram server:
  */
  #include <stdio.h>
  #include <unistd.h>
  #include <stdlib.h>
  #include <errno.h>
  #include <string.h>
  #include <time.h>
  #include <sys/types.h>
  #include <sys/socket.h>
  #include <netinet/in.h>
  #include <arpa/inet.h>

 /*
  * This function reports the error and
  * exits back to the shell:
  */
  static void displayError(const char *on_what) {
     fputs(strerror(errno),stderr);
     fputs(": ",stderr);
     fputs(on_what,stderr);
     fputc('\n',stderr);
     exit(1);
  }

  int main(int argc,char **argv) {
     int z;
     char *srvr_addr = NULL;
     struct sockaddr_in adr_inet; // AF_INET
     struct sockaddr_in adr_clnt; // AF_INET
     int len_inet;                // length
     int s;                       // Socket
     char dgram[512];             // Recv buffer
     char dtfmt[512];             // Date/Time Result
     time_t td;                   // Current Time and Date
     struct tm tm;                // Date time values

 /*
  * Use a server address from the command
  * line, if one has been provided.
  * Otherwise, this program will default
  * to using the arbitrary address
  * 127.0.0.
  */
     if ( argc >= 2 ) {
        // Addr on cmdline:
        srvr_addr = argv[1];
     }
     else {
        // Use default address:
        srvr_addr = "127.0.0.23";
     }

 /*
  * Create a UDP socket to use:
  */
     s = socket(AF_INET,SOCK_DGRAM,0);
     if ( s == -1 ) {
        displayError("socket()");
     }
 /*
  * Create a socket address, for use
  * with bind(2):
  */
     memset(&adr_inet,0,sizeof adr_inet);
     adr_inet.sin_family = AF_INET;
     adr_inet.sin_port = htons(9090);
     adr_inet.sin_addr.s_addr =
     inet_addr(srvr_addr);

     if ( adr_inet.sin_addr.s_addr == INADDR_NONE ) {
        displayError("bad address.");
     }
     len_inet = sizeof adr_inet;

 /*
  * Bind a address to our socket, so that
  * client programs can contact this
  * server:
  */
     z = bind(s, (struct sockaddr *)&adr_inet, len_inet);
     if ( z == -1 ) {
        displayError("bind()");
     }

 /*
  * Now wait for requests:
  */
     for (;;) {
 /*
  * Block until the program receives a
  * datagram at our address and port:
  */
        len_inet = sizeof adr_clnt;
        z = recvfrom(s,            // Socket
                     dgram,        // Receiving buffer
                     sizeof dgram, // Max recv buf size
                     0,            // Flags: no options
                     (struct sockaddr *)&adr_clnt, // Addr
                     &len_inet);  // Addr len, in & out
        if ( z < 0 ) {
           displayError("recvfrom(2)");
        }
 /*
  * Process the request:
  */
        dgram[z] = 0; // null terminate
        if ( !strcasecmp(dgram,"QUIT") ) {
           break;     // Quit server
       }

 /*
  * Get the current date and time:
  */
        time(&td);            // Get current time & date
        tm = *localtime(&td); // Get components

 /*
  * Format a new date and time string,
  * based upon the input format string:
  */
        strftime(dtfmt,       // Formatted result
                 sizeof dtfmt,// Max result size
                 dgram,       // Input date/time format
                 &tm);        // Input date/time values

 /*
  * Send the formatted result back to the
  * client program:
  */
        z = sendto(s,             // Socket to send result
                   dtfmt,         // The datagram result to snd
                   strlen(dtfmt), // The datagram lngth
                   0,             // Flags: no options
                   (struct sockaddr *)&adr_clnt,// addr
                   len_inet);     // Client address length
       if ( z < 0 ) {
          displayError("sendto(2)");
      }
    }
 /*
  * Close the socket and exit:
  */
     close(s);
     return 0;
  }

/*
 * When we run this program our server will come in listen 
 * state and is waiting to accept the client connection
 *
 [sgupta@rhel55x86 chap6]$ gcc dgramserver.c -o dgramserver
 [sgupta@rhel55x86 chap6]$ ./dgramserver 192.168.22.55

 */

See the UDP datagram client from here for complete appication

See Also:

3 comments: