home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!news.tek.com!psgrain!charnel!rat!usc!zaphod.mps.ohio-state.edu!darwin.sura.net!spool.mu.edu!hri.com!noc.near.net!ns.draper.com!news.draper.com!MVS.draper.com!SEB1525
- From: SEB1525@MVS.draper.com (Steve Bacher)
- Newsgroups: comp.unix.programmer
- Subject: UDP bidirectional socket problem
- Message-ID: <19921110153355SEB1525@MVS.draper.com>
- Date: 10 Nov 92 20:33:00 GMT
- Sender: MVS NNTP News Reader <NNMVS@MVS.draper.com>
- Organization: Draper Laboratory
- Lines: 209
- Nntp-Posting-Host: mvs.draper.com
-
-
- Please excuse me, those of you who saw this on comp.sys.sun.apps...
-
- We have a program that sets up 2 UDP peer-to-peer sockets between two
- Suns. If both Suns are Sun-3's, they can read and write between 2
- processes using 1 socket on each side. If the Sun-3 talks to the Sparc,
- then single sockets don't work - you end up needing 4 sockets, 2 on each
- side, 1 read and 1 write.
-
- Here is the program, along with 2 calling programs, to demonstrate the
- problem. Each program takes the name of remote machine to talk to.
- You run sock1 on one host and subsequently sock2 on the other.
- sock1 writes a message to the other host, where sock2 reads it.
- Then sock2 reads a reply from the machine running sock1.
-
- If I start sock1 on the sun4 and then start sock2 on the sun3,
- sock1 hangs waiting for sock2 to send it something. sock2 appears
- never to return from the write to sock1.
-
- If I start sock1 on the sun3 and then start sock2 on the sun4, sock1
- hangs and sock2 complains on the read because it did not block after the
- write. No non-blocking has been specified.
-
- We can get a message through if we disconnect the socket on 1 side.
- Executing the connect() call on the sun4 somehow screws things up.
-
- Note that read() normally blocks. sock1 does read() and waits and
- blocks just fine. But if you have written to the socket, the first time
- you read from it it is nonblocking, so you have to force a loop to
- actually get it to block - the second one blocks.
-
- I compared the output of the C preprocessor on the programs compiled on
- the sun3 and sun4. The only significant difference is in the definition
- of the type physadr_t in /usr/include/sys/types.h, which is a struct
- containing a short on the sun-3 but a struct containing an int on a
- Sparc. This doesn't seem to be used anywhere, though.
-
- Here are the sample programs.
-
- ------------------------------------------------------------------------
- makefile
- ------------------------------------------------------------------------
-
- sock1: sock1.o sock.o
- cc -o sock1 sock1.o sock.o
-
- sock2: sock2.o sock.o
- cc -o sock2 sock2.o sock.o
-
- sock.o: recomp sock.c
- cc -c sock.c
-
- sock1.o: sock1.c
- cc -c sock1.c
-
- sock2.o: sock2.c
- cc -c sock2.c
-
- recomp:
- -rm sock.o
-
- ------------------------------------------------------------------------
- sock.c
- ------------------------------------------------------------------------
-
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/time.h>
- #include <stdio.h>
- #define MAX_MLEN 128
- #define TRUE 1
- #define FALSE 0
-
- int sock;
- char msg[MAX_MLEN];
-
- set_socks(remote_host)
- char *remote_host;
- {
- struct hostent *remote_ent;
- unsigned long *remote_addr;
- struct sockaddr_in remote_name,my_name;
- int optval = TRUE;
-
- sock = socket(AF_INET, SOCK_DGRAM, 0);
- if (sock < 0)
- {
- perror("Error opening socket ");
- return(FALSE);
- }
-
- my_name.sin_family = AF_INET;
- my_name.sin_addr.s_addr = htonl(INADDR_ANY);
- my_name.sin_port = htons(5002); /* write to me here */
-
- if (bind(sock, (struct sockaddr *) &my_name, sizeof(my_name)) < 0)
- {
- perror("Error binding my socket to my name");
- return(FALSE);
- }
-
- remote_ent = (struct hostent *) gethostbyname(remote_host);
- remote_addr = (unsigned long *) remote_ent->h_addr;
- remote_name.sin_family = AF_INET;
- remote_name.sin_addr.s_addr = *remote_addr;
- remote_name.sin_port = htons(5002);
-
- if(connect(sock, (struct sockaddr *) &remote_name,sizeof(remote_name)) < 0)
- {
- perror("Error connecting to remote port");
- return(FALSE);
- }
- return(TRUE);
- }
-
-
- host2(sendto)
- char *sendto;
- {
- #define namelen 64
- int i,j;
- char me[namelen];
- gethostname(me,namelen);
- strcpy(msg,"Hello ");
- strcat(msg, sendto);
- strcat(msg, " Love, ");
- strcat(msg,me);
- strcat(msg,"\n");
- printf("about to set socks on %s\n",me);
- if(set_socks(sendto)){
- printf("about to write the following message to %s ::\n",sendto);
- printf("%s",msg);
- if(write(sock,msg,MAX_MLEN)<0)
- {
- perror("write error");
- return(FALSE);
- }
- j=0;
- while((i=read(sock,msg,MAX_MLEN)) < 0)
- {
- j += 1;
- printf("read did not block after write\n");
- }
- printf(
- "Got %d byte message from %s after %d read attempts. Msg: %s\n",
- i,sendto,j,msg);
- }
- else exit(1);
- }
-
- host1(sendto)
- char *sendto;
- {
- #define namelen 64
- int i;
- char me[namelen];
-
- gethostname(me,namelen);
- printf("about to set socks on %s\n",me);
- if(set_socks(sendto)){
- printf("about to wait for a message from %s ::\n",sendto);
- i=read(sock,msg,MAX_MLEN);
- printf("%s",msg);
- strcpy(msg,"Bye ");
- strcat(msg, sendto);
- strcat(msg, " Love, ");
- strcat(msg,me);
- strcat(msg,"\n");
- printf("about to send reply to %s\n", sendto);
- sleep(2);
- if(write(sock,msg,MAX_MLEN)<0)
- {
- perror("write error");
- }
- }
- else exit(1);
- close(sock);
- }
-
- ------------------------------------------------------------------------
- sock1.c
- ------------------------------------------------------------------------
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- host1(argv[1]);
- }
-
- ------------------------------------------------------------------------
- sock2.c
- ------------------------------------------------------------------------
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- host2(argv[1]);
- }
-
-
- --
- Steve Bacher (Batchman) Draper Laboratory
- Internet: seb@draper.com Cambridge, MA, USA
-