Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!caip!lll-crg!seismo!umcp-cs!chris From: chris@umcp-cs.UUCP (Chris Torek) Newsgroups: net.lan Subject: Re: bsd networking primitives Message-ID: <2745@umcp-cs.UUCP> Date: Tue, 5-Aug-86 22:13:43 EDT Article-I.D.: umcp-cs.2745 Posted: Tue Aug 5 22:13:43 1986 Date-Received: Thu, 7-Aug-86 05:57:51 EDT References: <523@rna.UUCP> Reply-To: chris@maryland.UUCP (Chris Torek) Organization: University of Maryland, Dept. of Computer Sci. Lines: 268 In article <523@rna.UUCP> kc@rna.UUCP (Kaare Christian) writes: >For ipc in the Unix domain it seems that both parties need a bind >following socket creation, but when ipc is in the internet domain only >the server needs a bind. Why?? Sounds like a bug to me. It is not true in 4.3BSD beta-plus-upgrades. (See example programs below.) >Ques 2. When you use the internet domain, but client and server are on >the same machine, does your data go though the loop back connection? >Is this the reason for the loop back connection. Actually, that depends on the driver. Some Ethernet boards cannot send to themselves; so drivers for those will call the loopback driver in such cases. Other boards do not have this limitation, but usually the driver will call the loopback code anyway. I threw the following code together to see whether the client needed to bind before connecting. (It did not.) Extract the files (the script makes a fresh directory for them), compile, and run with an argument as to what socket to create. Careful: `se' (the server) removes any file with the same name as that socket. : Run this shell script with "sh" not "csh" PATH=/bin:/usr/bin:/usr/ucb:/etc:$PATH export PATH all=FALSE if [ x$1 = x-a ]; then all=TRUE fi echo Making directory test_AF_UNIX mkdir test_AF_UNIX echo Extracting test_AF_UNIX/Makefile sed 's/^X//' <<'//go.sysin dd *' >test_AF_UNIX/Makefile DESTDIR= CFLAGS= -O STD= cl se all: ${STD} ${STD}: error.o ${CC} ${CFLAGS} -o $@ $@.c error.o install: @echo "test programs are never installed, silly!" clean: rm -f *.o *.s a.out core *.bak rm -f ${STD} depend: for i in ${STD} error; do \ ${CC} -M $$i.c | sed -e 's/\.o//' | \ awk '{ if ($$1 != prev) { if (rec != "") print rec; \ rec = $$0; prev = $$1; } \ else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \ else rec = rec " " $$2 } } \ END { print rec }'; done >makedep echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep echo '$$r makedep' >>eddep echo 'w' >>eddep cp Makefile Makefile.bak ed - Makefile >Makefile echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >>Makefile echo '# see make depend above' >>Makefile # DO NOT DELETE THIS LINE -- make depend uses it cl: cl.c /usr/include/stdio.h /usr/include/sys/types.h cl: /usr/include/sys/socket.h /usr/include/sys/un.h se: se.c /usr/include/stdio.h /usr/include/sys/types.h se: /usr/include/sys/socket.h /usr/include/sys/un.h error: error.c /usr/include/stdio.h # DEPENDENCIES MUST END AT END OF FILE # IF YOU PUT STUFF HERE IT WILL GO AWAY # see make depend above //go.sysin dd * if [ `wc -c < test_AF_UNIX/Makefile` != 1238 ]; then made=FALSE echo error transmitting test_AF_UNIX/Makefile -- echo length should be 1238, not `wc -c < test_AF_UNIX/Makefile` else made=TRUE fi if [ $made = TRUE ]; then chmod 644 test_AF_UNIX/Makefile echo -n ' '; ls -ld test_AF_UNIX/Makefile fi echo Extracting test_AF_UNIX/cl.c sed 's/^X//' <<'//go.sysin dd *' >test_AF_UNIX/cl.c X/* * client */ #include #include #include #include #define suntosa(x) ((struct sockaddr *) (x)) #define namesize(x) (strlen((x)->sun_path) + sizeof ((x)->sun_family)) struct sockaddr_un servname; int servsock; extern int errno; char *strcpy(); main(argc, argv) int argc; char **argv; { char buf[20]; if (argc < 2) error(1, 0, "usage: cl "); if ((servsock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) error(1, errno, "socket"); servname.sun_family = AF_UNIX; (void) strcpy(servname.sun_path, argv[1]); if (connect(servsock, suntosa(&servname), namesize(&servname))) error(1, errno, "connect"); if (write(servsock, "hi", 2) != 2) error(1, errno, "write"); if (read(servsock, buf, 5) != 5) error(1, errno, "read"); buf[5] = 0; printf("\"hi\" => \"%s\"\n", buf); exit(0); } //go.sysin dd * if [ `wc -c < test_AF_UNIX/cl.c` != 855 ]; then made=FALSE echo error transmitting test_AF_UNIX/cl.c -- echo length should be 855, not `wc -c < test_AF_UNIX/cl.c` else made=TRUE fi if [ $made = TRUE ]; then chmod 644 test_AF_UNIX/cl.c echo -n ' '; ls -ld test_AF_UNIX/cl.c fi echo Extracting test_AF_UNIX/error.c sed 's/^X//' <<'//go.sysin dd *' >test_AF_UNIX/error.c X/* * For other systems... mine comes from my C library. */ #ifdef lint X/*VARARGS3 ARGSUSED*/ error(quit, e, fmt) int quit, e; char *fmt; {;} #else #include char *_argv0; /* set by C start up code before calling main */ error(quit, e, fmt, args) int quit; register int e; char *fmt; { extern char *sys_errlist[]; extern int sys_nerr; if (_argv0) (void) fprintf(stderr, "%s: ", _argv0); _doprnt(fmt, &args, stderr); if (e) { if (e < sys_nerr) (void) fprintf(stderr, ": %s", sys_errlist[e]); else (void) fprintf(stderr, ": unknown error code %d", e); } (void) putc('\n', stderr); (void) fflush(stderr); if (quit) exit(quit); } #endif //go.sysin dd * if [ `wc -c < test_AF_UNIX/error.c` != 677 ]; then made=FALSE echo error transmitting test_AF_UNIX/error.c -- echo length should be 677, not `wc -c < test_AF_UNIX/error.c` else made=TRUE fi if [ $made = TRUE ]; then chmod 644 test_AF_UNIX/error.c echo -n ' '; ls -ld test_AF_UNIX/error.c fi echo Extracting test_AF_UNIX/se.c sed 's/^X//' <<'//go.sysin dd *' >test_AF_UNIX/se.c X/* * server */ #include #include #include #include #define suntosa(x) ((struct sockaddr *) (x)) #define namesize(x) (strlen((x)->sun_path) + sizeof ((x)->sun_family)) struct sockaddr_un servname, cliname; int servsock, clisock; extern int errno; char *strcpy(); main(argc, argv) int argc; char **argv; { char buf[20]; int fromlen; if (argc < 2) error(1, 0, "usage: se "); if ((servsock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) error(1, errno, "socket"); (void) unlink(argv[1]); /* clear the way */ servname.sun_family = AF_UNIX; (void) strcpy(servname.sun_path, argv[1]); if (bind(servsock, suntosa(&servname), namesize(&servname))) error(1, errno, "connect"); if (listen(servsock, 1)) error(1, errno, "listen"); fromlen = sizeof (cliname); if ((clisock = accept(servsock, suntosa(&cliname), &fromlen)) < 0) error(1, errno, "accept"); if (read(clisock, buf, 2) != 2) error(1, errno, "read"); if (write(clisock, "there", 5) != 5) error(1, errno, "write"); exit(0); } //go.sysin dd * if [ `wc -c < test_AF_UNIX/se.c` != 1063 ]; then made=FALSE echo error transmitting test_AF_UNIX/se.c -- echo length should be 1063, not `wc -c < test_AF_UNIX/se.c` else made=TRUE fi if [ $made = TRUE ]; then chmod 644 test_AF_UNIX/se.c echo -n ' '; ls -ld test_AF_UNIX/se.c fi made=TRUE if [ $made = TRUE ]; then chmod 755 test_AF_UNIX echo -n ' '; ls -ld test_AF_UNIX fi -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@mimsy.umd.edu