[GRASS5] socket server sample in programman

Daniel Isenegger disen at geo.unizh.ch
Thu Sep 11 09:41:51 EDT 2003


Hi
I try to access GRASS from a C progamm via sockets.
I found in the GRASS 5.0 Programmer's Manual on S.208 das Trivial Socket 
  Server (socketServer_grass.c) example and to learn the handling I try 
to  customize it to the status that:
a client process (client3.c) sends a message to Trivial Socket Server 
and  the Trivial Socket Server just sends back the message.

I can do this (without GRASS) with normal C-programms (client.c and 
server3.c), but with the Trivial Socket Server example I'm stuck:

- what exactly is the argument to give to the Trivial Socket  Server example
(in the description: takes a simple name for a communication channel and 
  builds the full path for a socket file with that name)
- how is the host:port specified? for example in client.c it is done 
explicitely:
(line 35 ff  addr.sin_port = 9836; addr.sin_addr.s_addr = 
inet_addr("127.0.0.1");

thanx a lot			Dani
-------------- next part --------------
/*
* A simple client-applikation that sends a string to a server and receives its answer.
*/

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

#define SOCKET_NAME "sockli"

#define DATA "The time has come..."

int main(void) 
{ 
        int sock, len; 
        int n, result; 
        char buf[256] = DATA; 
        
        struct sockaddr_un addr = {0}; 

        sock = socket(AF_UNIX, SOCK_DGRAM, 0); 

        if(!sock) 
        { 
                perror("Socket could not be created"); 
                exit(1); 
        } 

        /* setup the address */ 
        /*addr.sin_family = AF_INET; 
        addr.sin_port = 9836; 
        addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
        len = sizeof(addr); */

 		addr.sun_family = AF_UNIX;
        strcpy(addr.sun_path, SOCKET_NAME);
        len = sizeof(addr);	

        n = sendto(sock, buf, strlen(buf), 0, (struct sockaddr *)&addr, len); 

        if(n != strlen(buf)) 
        { 
                perror("sendto failed"); 
                exit(1); 
        } 
		
        memset(buf, '\0', 256);

		unlink(SOCKET_NAME);
 		addr.sun_family = AF_UNIX;
        strcpy(addr.sun_path, SOCKET_NAME);
        len = sizeof(addr);		

        result = bind(sock, (struct sockaddr *)&addr, len); 

        if(result < 0) 
        { 
                perror("Could not bind to socket"); 
                exit(1); 
        }

        n = recvfrom(sock, buf, 256, 0, (struct sockaddr *)&addr, &len); 

        if(n < 1) 
        { 
                fprintf(stderr, "server3: received data of illigal size\n"); 
                exit(1); 
        } 
		
		printf("SERVER REPLY: %s", buf);

        close(sock); 
} 
-------------- next part --------------
/* Begin server3.c */ 
/* By William D. Larry [Ellectr0n] - Saturday, August 21, 2001 */ 
/* Copyright  2001(c) William D. Larry <wdlarry at hotmail.com> */ 
/* This program code is licensed under the GLP. Please read GPL for more information */ 
/* here we go... */ 

/*
* A simple Server-Applikation, that receives a String and answers to the client.
*/

/* Include neccessery header files */ 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <stdio.h> 
#include <netinet/in.h> 
#include <sys/un.h> 
#include <arpa/inet.h> 
#include <unistd.h> 

#define SOCKET_NAME "sockli"

int main(void) 
{ 
        int sock, len; 
        int result; 
        int n; 
        char buf[256]; 
        //struct sockaddr_in addr; 
        struct sockaddr_un addr = {0}; 

        sock = socket(AF_UNIX, SOCK_DGRAM, 0); 

        if(!sock) 
        { 
                perror("creating dgram socket"); 
                exit(1); 
        } 

        memset(&addr, 0, sizeof(addr)); 

        /* set up the address */ 
        /*addr.sin_family = AF_INET; 
        addr.sin_port = 9836; 
        addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
        len = sizeof(addr); */

		unlink(SOCKET_NAME);
 		addr.sun_family = AF_UNIX;
        strcpy(addr.sun_path, SOCKET_NAME);
        len = sizeof(addr);		

        result = bind(sock, (struct sockaddr *)&addr, len); 

        if(result < 0) 
        { 
                perror("binding to dgram socket"); 
                exit(1); 
        }

        n = recvfrom(sock, buf, 256, 0, (struct sockaddr *)&addr, &len); 
		buf[n] = '\0';
		
        if(n < 1) 
        { 
                /* received less than 1 byte... that's illigal! */ 
                fprintf(stderr, "server3: received data of illigal size\n"); 
                exit(1); 
        } 

       	printf("RECEIVED FROM CLIENT: %s\n", buf);

        memset(buf, '\0', 256); 
        strcpy(buf, "\n\nHallo Client\n\n");
 		
 		addr.sun_family = AF_UNIX;
        strcpy(addr.sun_path, SOCKET_NAME);
        len = sizeof(addr);
        
        n = sendto(sock, buf, strlen(buf), 0, (struct sockaddr *)&addr, len); 

        if(n != strlen(buf)) 
        { 
                perror("sendto failed"); 
                exit(1); 
        } 

        close(sock); 
        
        //printf("\n\nSENT: %d, LEN: %d\n\n", n, strlen(buf));
} 

-------------- next part --------------
#include <stdio.h>
#include <stdlib.h> 
#include <errno.h> 
#include "gis.h" 

int main (int argc, char *argv[]) 
{ 
  int listenfd, rwfd; 
  char *path; 
  pid_t pid; 
  struct sockaddr_un addr = {0};
  /* Path is built using server's name */ 
  // path: F-des
  if (NULL == (path = G_sock_get_fname (argv[0]))) 
    exit (EXIT_FAILURE); 

  /* Make sure another instance isn't running */ 
  if (G_sock_exists (path)) 
  { 
    if ((listenfd = G_sock_connect (path)) != -1) 
    { 
      close (listenfd);
      exit (EXIT_FAILURE); 
    } 
    remove (path); 
  } 
  /* Bind the socket */ 
  // listenfd: F-des, path: F-des
  if ((listenfd = G_sock_bind (path)) < 0) 
    exit (EXIT_FAILURE); 

  /* Begin listening on the socket */ 
  // 1: int queue length, should never be = 0
  if (G_sock_listen (listenfd, 1) != 0) 
    exit (EXIT_FAILURE); 

  /* Loop forever waiting for connections */ 
  for (;;) 
  { 
    if ((rwfd = G_sock_accept (listenfd)) < 0) { 
      if (errno == EINTR) 
	continue; 
    } 
    else 
      exit (EXIT_FAILURE); 

    /* Fork connection */ 
    // parent process: listen to socket
    // child process: process request
    // pid: pid of new child process
    if ((pid = fork()) == 0) { 
      char c; 
      /* child closes listenfd */ 
      close (listenfd); 
      // rwfd: F-des, c: Zeichenvektor,aus dem Zeichen gelesen werden sollen
      // 1: Anz zu lesende bytes
      while (read (rwfd, &c, 1) > 0) 
	write (rwfd, &c, 1); // schreibt 1 char von c in rwfd
      close (rwfd); 
      return 0; 
    } 
    else if (pid > 0) { 
      /* parent closes rwfd 
       * a well behaved server would limit 
       * the number of forks. */ 
      close (rwfd); 
    } 
    else 
      exit (EXIT_FAILURE); 
  } 
  G_free (path); 
  return 0; 
} 


More information about the grass-dev mailing list