[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