From: erb@fullfeed.fullfeed.com (David Erb)
Newsgroups: comp.sys.sun.misc
Subject: problem: listen port not released on socket close...help?
Date: 23 Nov 92 01:21:50 GMT
Organization: FullFeed: Public Access Usenet/E-mail at +1 608 246 2701 guest

/*__________________________________________________________________________
 * Dear Netland.
 * Below is a test program to illustrate a problem with sockets.
 * When I run it several times in succession, I get the message:
 *    bind: Address already in use
 * Sometimes I get this message the second time, sometimes not until
 * the tenth.  After getting the message once, I will get the message
 * every time I run the program.  After 5 minutes or so without running
 * the program, the condition seems to clear itself and I can run again.
 * Doing a compile as stated below also seems to clear the condition.
 * After the condition has cleared, it will resurface after I run the
 * program a few times again.
 *
 * Any help would be greatly appreciated.  Please email me direct and
 * I will post a summary if warranted.
 *
 * SunOS 4.1.1 on Sun4/150 running X11R5 with xterm, epoch and xmeter.
 * Compile with either:
 *   cc -o socktest socktest.c
 *   gcc -o socktest socktest.c  (problem more frequent with gcc)
 *
 * program summary:
 * fork
 * if child (server)
 *   socket
 *   bind
 *   listen
 *   accept
 *   read
 *   write
 *   close and close
 * if parent (client)
 *   wait 2 secods for the server to make it to "accept"
 *   gethostbyname
 *   socket
 *   connect
 *   write
 *   read
 *   close
 * Thanks in advance.
 * David Erb, erb@fullfeed.com
 *__________________________________________________________________________*/

#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>

#include <rpc/xdr.h>

#include <fcntl.h>
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#include <netdb.h>

/*__________________________________________________________________________
 *__________________________________________________________________________*/
int
main(argc, argv)
  int argc;
  char *argv[];
{
  exit(socktest(argc, argv));
}

int
socktest(argc, argv)
  int argc;
  char *argv[];
{
  int server_sock, client_sock;
  struct sockaddr_in server;
  struct sockaddr_in client;
  struct hostent *hostentry;
  int clientlen;
  int rc, data;
  union wait status;

  memset(server, 0, sizeof(server));
  server.sin_port = htons(5702);        /* set service port                 */
  server.sin_family = AF_INET;

  rc = fork();
  if (rc == 0)                          /* we are the child?                */
  {                                     /* ====== SERVER ================== */
    server_sock = socket(AF_INET,       /* make the socket                  */
      SOCK_STREAM, 0);
    if (server_sock < 0)
      {perror("server socket"); return(1);}

    server.sin_addr.s_addr =            /* host we will talk to             */
      INADDR_ANY;

    rc = bind(server_sock,              /* bind server to service port      */
      &server, sizeof(server));
    if (rc < 0)
      {perror("bind"); return(1);}

    rc = listen(server_sock, 5);        /* mark socket as a listener        */
    if (rc < 0)
      {perror("listen"); return(1);}

    clientlen = sizeof(client);
    client_sock = accept(server_sock,   /* first accept connection          */
      &client, &clientlen);
    if (client_sock < 0)
      {perror("accept"); return(1);}

    rc = read(client_sock,              /* read from socket                 */
      &data, sizeof(data));
    if (rc == -1)
      {perror("server read"); return(1);}

    printf("server got data %d\n",
      data);
    data = data * data;

    rc = write(client_sock,             /* write into socket                */
      &data, sizeof(data));
    if (rc == -1)
      {perror("server write"); return(1);}

    close(client_sock);
    close(server_sock);
  }
  else                                  /* ======= CLIENT ================= */
  if (rc > 0)                           /* we are the parent?               */
  {
    sleep(1);                           /* let server get established       */
    server_sock = socket(AF_INET,       /* make socket                      */
      SOCK_STREAM, 0);
    if (server_sock < 0)
      {perror("client socket"); return(1);}

    hostentry = gethostbyname(          /* get host entry                   */
      "localhost");
    if (hostentry == 0)
    {perror("gethostbyname"); return(1);}

    server.sin_addr.s_addr =            /* host we want to talk to          */
      ((struct in_addr *)
        (hostentry->h_addr))->s_addr;

    rc = connect(server_sock,           /* bind local and connect foreign   */
      &server, sizeof(server));
    if (rc < 0)
      {perror("connect"); return(1);}

    data = 2;
    rc = write(server_sock,             /* write into socket                */
      &data, sizeof(data));
    if (rc == -1)
      {perror("client write"); return(1);}

    rc = read(server_sock,              /* read from socket                 */
      &data, sizeof(data));
    if (rc == -1)
      {perror("client read"); return(1);}

    printf("client got data %d\n",
      data);

    close(server_sock);                 /* close socket to server           */

    rc = wait(&status);                 /* see what child did               */
    if (rc < 0)
      {perror("wait"); return(1);}
  }
  else
  if (rc == -1)                         /* couldn't fork?                   */
    {perror("fork"); return(1);}

  return(0);
}
Newsgroups: comp.sys.sun.misc