goldstn@evax.arl.utexas.edu (David Goldstein) (02/08/91)
For quite some time I've been unable to debug TCP/IP code that behaves as follows: sockets are used to communicate at port #2700. the same code is used on each machine. sun4 -> sun4 fine sun4 -> sun3 fine sun3 -> sun4 connects properly, but sending gets bad address on the Unix "write".. seems as if the socket # is correct though sun3 -> sun3 " VAX (Ultrix) and Sun4 -> does not connect Can anyone give me some insight on this problem? Enclosed is some of the relevent source code, loaded with print statements for debugging. Thanks very much for even reading! David /********************************************************************** Name: Setup sockets Abstract: This routine sets up sockets for the interactive workstations. The white workstation connects at a reserved port. A server port is set up for the other workstations. The ports are set to be non-blocking so that an "accept" can be done in a loop without hanging. Revision History: 06/06/90 D. Goldstein ***********************************************************************/ #include <sys/types.h> /* #include <sys/socket.h> */ #include <stdio.h> #include <netinet/in.h> /* #include <netdb.h> */ #include <errno.h> #define SETUP_SOCKETS #include <ctype.h> #include "my_sockets.h" #include "tcmipc.h" #include "icm.h" #include "stats.h" #define TRUE 1 #define FALSE 0 /* extern int have_told_tcm_quitting; */ extern long int timer[20]; /* Make a socket and listen for connections */ int make_server_socket(serv_port) int serv_port; /* server port */ { extern struct hostent *gethostbyname(); struct hostent *rhp; int s, on =0; struct sockaddr_in raddress; s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) give_error("socket in make_server_socket"); /* look up address of the destination machine */ if ((rhp = gethostbyname(my_host_name)) == NULL) give_error("gethostbyname make_server_socket"); bzero((char *)&raddress, sizeof(raddress)); bcopy(rhp->h_addr,(char *)&raddress.sin_addr,rhp->h_length); raddress.sin_family = AF_INET; /* raddress.sin_addr.s_addr = INADDR_ANY; */ raddress.sin_port = serv_port; /* server port */ if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) give_error("setsocketopt in make_server_socket"); if (bind(s, (struct sockaddr *) &raddress, sizeof(struct sockaddr_in))) give_error("bind_socket"); if (listen(s, 10) < 0) give_error("listen make_server_socket"); return(s); } look_for_host(i,count) int i,count; { struct hostent *hp; extern struct sockaddr_in Host_addr; extern struct hostent *gethostbyname(); int sock; printf("Establishing connection to workstation on host |%s|\n",ws[i].name); hp = gethostbyname(ws[i].name); if (hp == (struct hostent *) 0) give_error("gethostbyname"); /* Get local host address */ bzero((char *)&Host_addr, sizeof(Host_addr)); bcopy(hp->h_addr, (char *)&Host_addr.sin_addr, hp->h_length); Host_addr.sin_family = AF_INET; Host_addr.sin_port = ws[i].adrs; printf("will accept %s at #%d\n",ws[i].name,ws[i].adrs); if ((sock=socket(AF_INET,SOCK_STREAM,0))<0) give_error("socket"); while (connect(sock,(struct sockaddr *)&Host_addr,sizeof(Host_addr))<0); printf("%s connected %d = TRUE at socket %d\n",ws[i].name,i,sock); connected[i] = TRUE; who_head = insert(ws[i].name,who_head,sock,TCP); return(sock); } b4accepting(i,count) int i,count; { sock[i] = make_server_socket(ws[i].adrs); if (dont_block(sock[i]) < 0) perror("Creating non-blocking pilot socket"); fprintf(stderr,"%s: B4listening, listening for %s at socket# %d.\n", my_host_name,ws[i].name,ws[i].adrs); } accepting(i) int i; { int g; g = accept(sock[i],0,0); /* modifies a copied socket */ if (g > 0) { sock[i] = g; fprintf(stderr,"%s: Connected at socket # %d: %s\n", progname,g,my_host_name); if (dont_block(sock[i])< 0) perror("Resetting non-blocking attributes"); connected[i] = TRUE; who_head = insert(ws[i].name,who_head,sock[i],TCP); printf("connected to proc %d= TRUE, %s uses socket %d\n", i,ws[i].name,sock[i]); } else if ( g < 0 && errno != EWOULDBLOCK) { fprintf(stderr,"%s: Error connecting %s\n", progname,my_host_name); perror("accepting connection"); } else { sleep(1); printf("in never-never land?\n"); /* Terminate(1); */ } } setup_sockets(count,vars) int count; char *vars[]; { int length,msgsock, connecting=0; struct sockaddr_in server; int g,i,j,c, iterat = 0; struct hostent *hp; extern struct sockaddr_in Host_addr; extern struct hostent *gethostbyname(); extern give_error(); /* NOTE: all 'C' arrays are 0-based, but command-line args 1-based, hence arrays are indices are compensated for */ last_ws = count; gethostname(my_host_name,HOST_NAME_LENGTH); printf("Hostname is %s of %d workstations\n",my_host_name, last_ws); for (i=0; i<last_ws; i++) if (strcmp(ws[i].name,my_host_name)<0) b4accepting(i,count); /* printf("\nHit 'C' to continue.\n"); while ('C' != getchar()); */ printf("Will start in 10 seconds....hurry up other machines!\n"); sleep(10); /* Handle case of all < self, create and accept socks */ while (connecting<last_ws) { iterat++; for (i=0; i<last_ws; i++) if (!connected[i]) if ((strcmp(ws[i].name,my_host_name)<0)) { /* printf("going to accepting\n"); */ accepting(i); if (connected[i]) connecting++; } else if (strcmp(ws[i].name,my_host_name)>0) { /* printf("look for host\n"); */ sock[i]=look_for_host(i,count); if (connected[i]) connecting++; else sleep(1); } if (!(iterat%10000)) printf("can't form a connection\n"); } printf("exiting setup sockets"); fact_message.type = FACTS; fact_message.num_facts = 0; }