Unix domain sockets demo programs

steveh at hammer.UUCP steveh at hammer.UUCP
Thu May 22 03:29:35 AEST 1986


# The rest of this file is a shell script which will extract:
# Makefile README client.c give.c server.c spair.c take.c
echo x - README
cat >README <<'!Funky!Stuff!'
These are demonstrations of Unix domain sockets.
They assume a bug fixed 4.2 (or 4.3) system.

0) To build the examples type:
	make

1) client/server example.
	# start server
	server /tmp/echo &
	# run client
	client /tmp/echo
	hello world...
	^D

2) give/take example.
	take /tmp/catch &
	give /etc/motd /tmp/catch

!Funky!Stuff!
echo x - Makefile
cat >Makefile <<'!Funky!Stuff!'
CFLAGS = -O
DEMOS = client server give take spair

all: ${DEMOS}

clean:;	rm -f *.o ${DEMOS}
!Funky!Stuff!
echo x - client.c
cat >client.c <<'!Funky!Stuff!'
/*
 * Connect to a unix domain server.
 */

#include <stdio.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define STDIN	0
#define STDOUT	1

main(argc,argv)
char **argv;
{
	int s;
	struct sockaddr_un sun;

	if(argc != 2) {
		fprintf(stderr, "Usage: client filename\n");
		exit(1);
	}

	if( (s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
		perror("socket");
		exit(1);
	}

	sun.sun_family = AF_UNIX;
	strcpy(sun.sun_path, argv[1]);

	if( connect(s, (struct sockaddr *) &sun, sizeof(sun)) < 0) {
		perror("connect");
		exit(1);
	}

	/* echo loop */
	for(;;) {
		int mask;

		mask = (1<<STDIN) | (1<<s);

		if(select(s+1, &mask, (int *) 0,  (int *) 0, 0) < 0) {
			perror("select");
			exit(1);
		}
		if(mask & (1<<s)) 
			if(copy(s, STDOUT) == 0)
				break;	/* end of file */
		if(mask & (1<<STDIN))
			if(copy(STDIN, s) == 0)
				break;
	}
}

copy(from, to)
{
	char buf[BUFSIZ];
	register int cc;

	cc = read(from, buf, sizeof buf);
	if(cc == 0)
		return 0;
	if(cc < 0) {
		perror("read");
		exit(1);
	}
	if(write(to, buf, cc) < 0) {
		perror("write");
		exit(1);
	}
	return cc;
}
!Funky!Stuff!
echo x - give.c
cat >give.c <<'!Funky!Stuff!'
/*
 * Pass a file to a process
 *
 * Usage: give file socket
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/uio.h>

struct sockaddr_un sun = { AF_UNIX };

main(argc, argv)
char **argv;
{
	int f, s;
	struct msghdr msg;
	struct iovec iov;

	if(argc != 3) {
		fprintf(stderr, "Usage: give file socket\n");
		exit(1);
	}
	if(strcmp(argv[1], "-") == 0)
		f = 0;
	else if( (f = open(argv[1],0)) < 0) {
		perror(*argv);
		exit(1);
	}
		
	if( (s = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
		perror("socket");
		exit(1);
	}
	strcpy(sun.sun_path, argv[2]);
	msg.msg_name = (caddr_t) &sun;
	msg.msg_namelen = sizeof sun;
	iov.iov_base = argv[1];
	iov.iov_len = strlen(argv[1]);
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	msg.msg_accrights = (caddr_t) &f;
	msg.msg_accrightslen = sizeof(f);

	fprintf(stderr, "give s=%d f=%d\n", f, s);
	if(sendmsg(s, &msg, 0) <  0) {
		perror("sendmsg");
		exit(1);
	}
}
!Funky!Stuff!
echo x - server.c
cat >server.c <<'!Funky!Stuff!'
/*
 * Unix domain echo server.
 */

#include <stdio.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define STDIN	0
#define STDOUT	1

main(argc,argv)
char **argv;
{
	register int cc, s, ns;
	char buf[BUFSIZ];
	int fromlen;
	struct sockaddr_un sun;
	struct sockaddr from;

	if(argc != 2) {
		fprintf(stderr, "Usage: echoserver filename\n");
		exit(1);
	}

	if( (s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
		perror("socket");
		exit(1);
	}

	sun.sun_family = AF_UNIX;
	strcpy(sun.sun_path, argv[1]);

	if( bind(s, (struct sockaddr *) &sun, sizeof(sun)) < 0) {
		perror("bind");
		exit(1);
	}

	listen(s, 1);

	fromlen = sizeof from;
	ns = accept(s, &from, &fromlen);
	if(ns < 0) 
		perror("accept");
	else
		while( (cc = read(ns, buf, sizeof buf)) > 0)
			if(write(ns, buf, cc) < 0) {
				perror("server write");
				break;
			}
	if(cc < 0)
		perror("server read");
	close(ns);
	close(s);
	unlink(sun.sun_path);	/* cleanup */
}
!Funky!Stuff!
echo x - spair.c
cat >spair.c <<'!Funky!Stuff!'
/*
 * demonstrate socketsv
 */
#include <stdio.h>

#include <sys/types.h>
#include <sys/socket.h>


main(argc, argv)
char **argv;
{
	register int child;
	int sv[2];

	if( socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0) {
		perror("socketpair");
		exit(1);
	}
	if(write(sv[0], "tick 00", 8) < 0 ||
	   write(sv[1], "tock 00", 8) < 0) {
		perror("write");
	   	exit(1);
	}
	child = fork();
	if(child < 0) 
		perror("fork");
	else if(child == 0) {
		flip(sv[0], sv[1]);
	} else {
		flip(sv[1], sv[0]);
		wait((int *) 0);
	}
}

flip(from, to)
{
	register int i;
	register int pid = getpid();
	char ibuf[32], obuf[32];;

	for(i = 0; i < 10; ++i) {
		if(read(from, ibuf, sizeof ibuf) < 0) {
			perror("read");
			return;
		}
		printf("%d: %s\n", pid, ibuf);
		sprintf(obuf, "%-4.4s %02d", ibuf, i);
		if(write(to, obuf, sizeof obuf) < 0) {
			perror("write");
			return;
		}
	}
	close(from);
	close(to);
}
!Funky!Stuff!
echo x - take.c
cat >take.c <<'!Funky!Stuff!'
/*
 * Receive a file on a socket
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/uio.h>

struct sockaddr_un sun = { AF_UNIX };

main(argc, argv)
char **argv;
{
	register int n;
	int s, f;
	struct sockaddr from;
	struct msghdr msg;
	struct iovec iov;
	char buf[8*1024];

	if(argc != 2) {
		fprintf(stderr, "Usage: take socket\n");
		exit(1);
	}
	if( (s = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
		perror("socket");
		exit(1);
	}
	strcpy(sun.sun_path, argv[1]);
	if( bind(s, &sun, sizeof sun) < 0) {
		perror("bind");
		exit(1);
	}
	msg.msg_name = (caddr_t) &from;
	msg.msg_namelen = sizeof from;
	iov.iov_base = buf;
	iov.iov_len = sizeof buf;
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	msg.msg_accrights = (caddr_t) &f;
	msg.msg_accrightslen = sizeof(f);

	fprintf(stderr, "take s=%d\n",s);
	n = recvmsg(s, &msg, 0);
	if(n <  0) {
		perror("recvmsg");
		unlink(sun.sun_path);
		exit(1);
	}
	fprintf(stderr, "take got f=%d\n", f);
	close(s);
	unlink(sun.sun_path);
	buf[n] = '\0';
	fprintf(stderr, ">%s<\n", buf);

	while( (n = read(f, buf, sizeof buf)) > 0)
		write(1, buf, n);
	if(n < 0)
		perror("read");
}
!Funky!Stuff!
-- 
  Stephen Hemminger		{ihnp4,decvax,ucbvax}!tektronix!hammer!steveh
  Tektronix GWD Networking	(503)685-2103
  



More information about the Comp.unix.wizards mailing list