[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Sun/Symbolics Ethernet I/F



	Date: Thu, 12 Jan 89 15:50:18 EST
	From: spike@starbase.mitre.org (Ben Bloom)


	I have a requirement to pass ascii strings over Ethernet between a
	Unix process and a Symbolics process. Could someone do me the
	tremendous favor of mailing code &/or instructions to open this 2-way
	I/O stream? Free duckpin lessons to the first kind soul.

	Thanks,
	Ben Bloom
	(spike@mitre.arpa)




I have recently been working on the same or a similar problem.  we have two
symbolics machines and one silicon graphics.  the idea was to have one 
symblx act as a message switcher between the others.  there are two special 
things i learned in this

	1. the unix system will allow the CLIENT functions to invoke any port,
	   BUT will allow only SERVER port numbers above 1024. unless, 
	   of course, you are logged in as the root.

	2. as described in sec 35.3.3 NFILE Charater Set Translation ,  
	   Networks, Vol 9, page 255ff, symbolics does not really run in  
	   ascii. so if your connection is always ascii<->symbolics, then set 
				D,#TD1PsT[Begin using 006 escapes](1 0 (NIL 0) (NIL :BOLD NIL) "CPTFONTCB"):ascii-translation t 
(2 0 (NIL 0) (NIL NIL NIL) "CPTFONT")	   in the 1define-server2 function.  if you don't do that, then look for 
           1-115 decimal2 as the newline character as it appears on the unix 
	   side, 1and add it to the end of the lines you send.


2the service entries in the symbolics namespace(s) fields are
 		service, medium, (local) protocol

		1 CALLIN2  TCP    MY-MESS-PASS2
		 ZING     TCP    ZINGER

2                 and in the unix ~/services file(s) are

		 1CALLIN2    1251/TCP
2		 1ZING       1252/TCP


2the following is hacked down from the message passing prototype.  the switching
service is callin2.  one of the functions is to invoke a service on either of 
the client machines.  this is called zing.  the switcher is a symbolics and the 
clients are the other symbolics and the silicon graphics.  the conversations are
two way and involve windows. if you want the rest
of the deathless code, or if there is a1 2question, just drop a line.




(3 0 (NIL 0) (NIL :ITALIC NIL) "CPTFONTI")Hillel      2sukenik@alexandria-emh2.mil




;;; -*- Syntax: Common-Lisp; Package: ZETALISP-USER; Base: 10; Mode: LISP -*-


(net:define-server :my-mess-pass2 (:medium :byte-stream	
				  :who-line "Gus Serving Marilyn"
				  :stream in
				  :host caller)
   (talk-to-me2 in caller)); talk-to-me is the service code

(1net:define-protocol :zinger2 (1:zing2 :byte-stream)
  (:invoke-with-stream (sap)
    sap) )

(tcp:add-tcp-port-for-protocol 1:my-mess-pass22 1251)1 
2			1;protocol for GUS'S service CALLIN2
2(tcp:add-tcp-port-for-protocol 1:zinger2 1252)1 
2			1;protocol for service ZING with GUS as client!


2(defun 1invoke-zinger2 (&key (server-host "Marilyn")); 
  (net:invoke-service-on-host 1:zing2 (si:parse-host server-host)) )



(defun 1talk-to-me22 (in host) 
  (format in "Hello, World Opening from Gus to ~A ~%Now, " host)

      ...
   ; here 1in2 is the read-write stream
   ; when the function-service 1zing2 is requested, 
   ;     function 1zinger-on-gus2 is invoked, ...



(defun 1zinger-on-gus2 (in host)
  (let* ((z-str (1invoke-zinger2 :server-host host))
	 
     ...

   ; here 1z-str2 is the i/o stream for the service on the other, usually
   ; client, but now server machine. 


   ...



1This is the code from the unix machine.  The first is from the client code, 
which runs in the foreground; the second is from the server code, which runs in 
the background2.1 this is built on the code in (4 0 (NIL 0) (NIL :BOLD-ITALIC NIL) "CPTFONTBI")An Introduction to BERKELY UNIX1, 
Paul Wang, Wadsdworth Publishing Company, 1988, chapter 10.  this is a fairly
decent basic treatment.  the port numbers problem, though, was brought to the
slug bb by John Parker (parker@stony-brook.scrc.symbolics.com) 22-JUL-88.


    --- client code ---

2#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <bsd/netdb.h>
#include <time.h>
#include <errno.h>
#include </esource/common/sys_parm.h>


struct sockaddr_in callin2 = {AF_INET};
struct servent *sp;
struct hostent *hp;
int s, i, j, k;
int mark = -115; 1/* this is the newline on the symbolics 
2			1as it appears to the unix */
2char buf[256], out_going[256];
FILE *fp;

1main2()

{
char str[132];
int loclv=FALSE, num;

	get_remote_socket_info("callin2", "gus", &callin2);
			1/* this loads structure callin2 */
2	s = socket(AF_INET, SOCK_STREAM, 0);
	printf ("\n\t THE socket number is %d", s);	
	if (s < 0) {perror ("callin2: socket"); exit (1);}

	if (connect (s, (char *)&callin2, sizeof(callin2)) < 0) 
		{        1/* like invoke-... */
2		perror("callin2: connect"); exit (1); }

	printf ("\n server says: \n");
	conver_in(s);   /* first read */
	
	while (TRUE)
		{
		1  ...
2		}
	close (s); 
	exit (0);
}






1get_remote_socket_info2(service,host,sock)
char *service, *host;
struct sockaddr_in *sock;

{
	hp = gethostbyname(host);
        printf ("\n\t here is the news from gethostbyname for %s", host);
	printf 
	  ("\n\t\t h_name: %s, h_addrtype %d, h_length %d, h_addr %s or %d\n",
          hp->h_name, hp->h_addrtype, hp->h_length, hp->h_addr, hp->h_addr);
	
	sp = getservbyname (service, "tcp");
	printf 
	  ("\n\n\t here is the news from getservbyname for %s via tcp", 
		service);
	printf ("\n\t\t s_name %s, s_port %d, s_proto %s or %d\n",
			sp->s_name, sp->s_port, sp->s_proto, sp->s_proto);

	if (sp == NULL){
	    printf(" \n get-remote-socket-info: %s/tcp unknown service",
			service);
	    exit (1);
	}
	if (hp == NULL){
	    printf("\n get-remote-socket-info: %s an unknown host\n", host);
	    exit (1);
	}

	bzero((char *)sock, sizeof(sock));
	bcopy (hp->h_addr, (char *)&sock->sin_addr, hp->h_length);
		1/* hp->h_addr is server internet address */
2	sock->sin_family = hp->h_addrtype;
	sock->sin_port   = sp->s_port;1    /* port for requested service */
2}



1   --- server code ---

2#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <bsd/netdb.h>
#include <errno.h>
#include </esource/common/sys_parm.h>


extern errno;
struct sockaddr_in sin={AF_INET};   /* listening socket */
int mark = -115;
char msg1[]={"I hope it is for cube.  That is all i can do!"};
char msg2[]={"i now need a number: "};

1main2()

{
int s;
struct sockaddr_in from;  /* caller info for forked process */
struct servent *sp;

	if ((sp = getservbyname ("zinger", "tcp")) == 0) {
		printf ("zinger: tcp/zinger: service unknown\n");
		exit (1);
		}1 /* load service entity structure sp */

2	sin.sin_port = sp->s_port;1   /* service offered on this port */
2	if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0) 1/* local socket */
2		{
		perror ("zinger: socket"); exit (1);
		}

	printf (" the port and socket numbers are %d %d %d \n",
			sin.sin_port, sp->s_port, s);
	if (bind (s, &sin, sizeof(sin)) < 0) 1/*link port-service to socket */
2		{
		perror ("zinger: bind"); exit (1); 
		}

	listen (s, 3); /* listen on local port */

	while (TRUE)
		{
		int ns, len = sizeof(from);

		if ((ns = accept(s, &from, &len)) < 0) /* ring-ring */
			{
			if (errno == EINTR) continue; /* never mind */
			perror("zinger-server: accept");
			continue; 
			}

		if (fork () == 0) 
			{		1/* child process */
2			close (s);
			zinger(ns, &from);
			}
		close (ns);		1/* parent process */
2		}  /* end of while */
} /* end of main */





1zinger2 (s, from)1  /* the server-function code */
2int s; /* read and write this accepted socket */
struct sockaddr_in *from;  /* this is the callers info */

{
char buf[256], str[132], word[35], c;
struct hostent *hp;  /* we'll get calling host name in here */
u_long hip;
int i, j, k;


	hp = gethostbyaddr(&from->sin_addr.s_addr, sizeof(hip), AF_INET);
	sprintf(str, 
		"hello to %s from zinger on Iris%cWhat is your wish?%c",
		hp->h_name, mark, mark);
	write (s, str, strlen(str));
	while (TRUE)
		{
		1   ...
2		}
	close (s);
	exit (0);
}