[comp.protocols.tcp-ip] Host Lockup During Socket Transfers

THIER@ORCAD2.dnet.ge.com (05/07/91)

   In attempting to run TCP socket transfers between two processes
residing in the same SPARCstation host, I am experiencing system 
lock-up after some number of transfers have taken place (the number
of transfers varys; it's usually between 950 and 2850 with 30 ms. 
intermessage spacing). Message sizes are 4446 octets. System 
configuration is:

                  SPARCstation 1+
                  SunOS 4.1
                  GENERIC Kernel.
                  16 MB memory.
                  210 MB disk.
                  56MB swap.
                  Send/Receive Queues = 4096


   I appear to be running out of some system resource that is reclaimed
after time, as the transfers can be extended somewhat by stopping the
transmit process prior to the lockup, waiting awhile, then restarting.
I've tried upping MAXUSERS to 16, with no effect. pstat -s shows no
appreciable inpact on swap, just prior to the lockup. Netstat shows the
many closing connections in TIME_WAIT, but nothing that seems wrong.
A typical netstat -m (at the 750 message mark) shows:

244/448 mbufs in use:
        7 mbufs allocated to packet headers
        96 mbufs allocated to socket structures
        135 mbufs allocated to protocol control blocks
        2 mbufs allocated to routing table entries
        2 mbufs allocated to socket names and addresses
        2 mbufs allocated to interface addresses
0/16 cluster buffers in use
72 Kbytes allocated to network (42% in use)
0 requests for memory denied
0 requests for memory delayed
0 calls to protocol drain routines

streams allocation:
                                         cumulative  allocation
                      current   maximum       total    failures
streams                    11        11         193           0
queues                     38        38         508           0
mblks                      15        39       57043           0
dblks                      15        39       57043           0
streams buffers:
external                    0         0           0           0
within-dblk                 0         4       29675           0
size <=    16               1        25       25725           0
size <=    32               0         3        1256           0
size <=   128              14        16         387           0
size <=   512               0         0           0           0
size <=  1024               0         0           0           0
size <=  2048               0         0           0           0
size <=  8192               0         0           0           0
size >   8192               0         0           0           0


   Any insight into what I'm doing wrong would be GREATLY appreciated (see
source below). TIA.


/* SERVER PROGRAM
   --------------

This routine creates a TCP socket and binds to the port number given
from argv [1]. It executes the following functional loop:

   Create Connection Socket
   Fetch Port Number from command line.
   BIND Connection Socket to port.
   LISTEN for connections.
   Loop:
      Test for connections with SELECT.
      ACCEPT Connection.
      Test for Data with SELECT.
      Loop until 4446 bytes received:
         RECV data.
      End Loop;
   End Loop;

   For every fifty complete messages received, the current message
   count is printed to the screen.

*/

#include <sys/types.h>;
#include <sys/time.h>;
#include <sys/socket.h>;
#include <stdio.h>;
#include <netdb.h>;
#include <netinet/in.h>;
#include <sys/uio.h>;
#include <strings.h>;
#include <stdio.h>;

main(argc, argv)
int argc;
char *argv[];

{

#define   BUFFER_SIZE   0xb000
#define   COUNT   50

   extern   errno;
   int    server_sd;
   int    msg_sd;
   int    char_count = 9; 
   char   buf[BUFFER_SIZE];
   int    rx_port;
   int    message_count;
   int    last_count;
   int    selectability;
   char   hostname[7];
   int    octets_received;
   struct timeval   *timeptr;
   fd_set readmask;
   fd_set writemask;
   fd_set exceptmask;
	
	struct	sockaddr_in	 	server;

   struct   hostent   *server_ent;


   /******************/
   /* Initialization */
   /******************/

   FD_ZERO (&writemask);
   FD_ZERO (&exceptmask);		
   timeptr = 0;
			
   message_count = 0;
   last_count = 0;

					 
   /*********************************************/
   /* Create and name Server INET STREAM socket */
   /*********************************************/
					
   printf ("\n\n\Server: Creating  INET STREAM socket.\n\n");
	
   server_sd = socket(AF_INET, SOCK_STREAM, 0);
	
   if (server_sd == -1)
   {

      perror("Server: Error creating socket.");

   }
	else
	{		
			
      sprintf (hostname,"loghost");

      server_ent = gethostbyname (hostname);

      if (server_ent == 0)
      {

         perror("Server: Unknown host.");

      }
      else
      {		

         printf("\n\Server: Hostname is %s\n",server_ent->h_name);

         /**************************/
         /* Bind Address to Socket */
         /**************************/

         bzero( (char *)&server, sizeof(server));
			
         server.sin_family = server_ent -> h_addrtype;
					
         bcopy ( (char *)server_ent -> h_addr,
                 (char *)&server.sin_addr,
                 server_ent -> h_length);

         printf("\n\Server: Internet Address is %s",inet_ntoa(server.sin_addr)); 
								

					 
         rx_port = atoi( argv[1] );

         server.sin_port = (short)rx_port;

         printf ("\n\n\Server: Local Port Number is  %i\n\n",server.sin_port);		

         if (bind	(server_sd, 
                  (struct sockaddr_in *)&server,
                   sizeof(struct sockaddr_in) ) == -1)
            {

               perror("Server: Error binding socket");
				
            }
            else
				{
             
               printf ("\n\n\Server: Socket bound to name 'server_sock'\n\n");


               /***************************/
               /*  Listen for Connections */
               /***************************/
	
               listen(server_sd, 5);

               printf ("\n\n\Server: Listening for connection.\n\n");


               /************************/
               /* Execute Receive Loop */
               /************************/

               while (1)
               {

                  /*******************************/
                  /* Pend on Connection Attempt. */
                  /*******************************/

                  FD_ZERO (&readmask);		
                  FD_SET (server_sd, &readmask);

                  selectability = select (FD_SETSIZE,
                                          &readmask,
                                          &writemask,
                                          &exceptmask,
                                          timeptr);

                  if (selectability > 0)
                  {

                     if FD_ISSET (server_sd, &readmask)
                     {

                        msg_sd = accept (server_sd, 
                                        (struct sockaddr_in *)0,
                                         sizeof(struct sockaddr_in) );

                        if (msg_sd == -1)
                        {

                           perror("Server: Error accepting connection");

                        }
                        else
                        {
					
                           /*****************/
                           /* Pend on Data. */
                           /*****************/

                           FD_ZERO (&readmask);		
                           FD_SET (msg_sd, &readmask);

                           selectability = select (FD_SETSIZE,
                                                   &readmask,
                                                   &writemask,
                                                   &exceptmask,
                                                   timeptr);

                           if (selectability > 0)
                           {

                              if FD_ISSET (msg_sd, &readmask)
                              {
   
                                 message_count = message_count + 1;
                                 octets_received = 0;

                                 while (octets_received < 4446)
                                 {
                                    char_count = 1;

                                    char_count = recv(msg_sd,
                                                      buf,
                                                      BUFFER_SIZE,
                                                      0);

                                    if (char_count == -1)
                                    {
                           
                                       perror("Server: Error receiving data.");

                                    }; /* End RECV Check */

                                    octets_received = octets_received +
                                          char_count;

                                 };   /* End Receive Loop. */		

                                 close (msg_sd);

                                 if (message_count - last_count == COUNT)
                                 { 
                                    printf ("\n\n%i", message_count);
                                    printf ("\ messages received.\n\n");                                              last_count = message_count;

                                 };   /* End Periodic Message. */

                              };   /* End Data Readability Check. */

                           }
                              else 
                           {

                              perror("Server: Error on Data Select.");
  
                           };   /* End Data Select Check. */

                        };   /* End Accept Check */

                     };   /* End Connection Check. */
				
                  };   /* End Connection Select Check. */

               }; /* End Input Loop */

					close (server_sd);

				};	/* End Bind Check */

			};	/* End Gethostname conditional */
			
		};	/* End Socket Create Conditional */

		printf ("\n\n\Server: Terminating.\n\n");

	  exit();

  } /* end main */



/* CLIENT PROGRAM
   --------------

This routine creates a TCP socket and connects to the host and port given
from argv [1] and [2], respectively. It executes the following functional 
loop:

   Fetch Server hostname and port number from command line.
   Loop for CONNECTION_LOOPS (currently set to 3000):
      Create socket.
      CONNECT to Server.
      Test for writability of socket with SELECT.
      SEND data (4446 bytes of ASCII 5's).
      Close socket.
   End Loop;
*/


#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/time.h>

main(argc, argv)
int argc;
char *argv[];
{
#define   BUFFER_SIZE   4446
#define   CONNECTION_LOOPS   3000

	extern	errno;
	int		client_sd; 
   int		output_cnt;
	int		i;
	int		cntd; 
	int 		rx_port;
   int      selectability;
   int      unix_call_status;

   struct   timeval   current_time;
   struct   timeval   previous_time;

   struct   timezone      system_time_zone;
   long     delta_seconds;
   long     delta_microseconds;
 
	struct	sockaddr_in	 	server;
	struct	sockaddr_in		client;


   struct   hostent   *server_ent;
   struct   hostent   *client_ent;


   char   buf_out[BUFFER_SIZE];
   char   hostname[25];

   fd_set readmask;
   fd_set writemask;
   fd_set exceptmask;
   struct timeval timeout;

   /******************/
   /* Initialization */
   /******************/

   for (i = 0; i < BUFFER_SIZE; i++)
   {
   
      buf_out[i] = '5';

   };

   cntd = 1;

   FD_ZERO (&readmask);
   FD_ZERO (&exceptmask);		

   timeout.tv_sec = 2;
   timeout.tv_usec = 0;

   system_time_zone.tz_minuteswest = 0;
   system_time_zone.tz_dsttime = DST_GB;

   /********************************************/					
   /* Fetch Client Host Data from '/etc/hosts '*/
   /********************************************/
		
   sprintf (hostname,"loghost");
   client_ent = gethostbyname (hostname);
			
   if (client_ent == 0)
   {
      perror("Client: Unknown local host.");
   }
      else
   {		

      printf("\n\Client: Hostname is %s\n",client_ent->h_name);
      printf("\n\Alias is %s\n",*((char *)client_ent->h_aliases)); 
		

      /*******************************************************/		
		/* Load Client Socket Structure with Host information. */
      /*******************************************************/	
		
      bzero( (char *)&client, sizeof(client));
		
      client.sin_family = client_ent -> h_addrtype;
      printf ("\n\Client: Domain Type is  %i\n\n",client.sin_family);
				
      bcopy ( (char *)client_ent -> h_addr,
              (char *)&client.sin_addr,
              client_ent -> h_length);
      printf("\n\Client: Internet Address is %s",inet_ntoa(client.sin_addr)); 
								


      /*********************************************************/
      /* Load Client Socket Structure with Server information. */
      /*********************************************************/

      server_ent = gethostbyname (argv[1]);
		
      if (server_ent == 0)
      {
         perror("Client: Unknown server host.");
      }
      else
      {		
         printf("\n\Client: Server hostname is %s\n",server_ent->h_name);

         bzero( (char *)&server, sizeof(server));
			
         server.sin_family = server_ent -> h_addrtype;
					
         bcopy ( (char *)server_ent -> h_addr,
                 (char *)&server.sin_addr,
                 server_ent -> h_length);

         printf("\n\Client: Server Address is %s",inet_ntoa(server.sin_addr));

         rx_port = atoi(argv[2]);

         server.sin_port = (short)rx_port;

         printf ("\n\n\Client: Server Port Number is  %i\n\n",server.sin_port);							

         /********************************/
         /* Commence Connect & Send Loop */
         /********************************/

         /**********************/
         /* Connect to Server. */
         /**********************/		

         for (i = CONNECTION_LOOPS; ( (0 < i) && (cntd != 0) ); i--)

         {
            /************************/
				/* Create client socket */
            /************************/

            if ( (client_sd = socket(AF_INET, SOCK_STREAM, 0) ) == -1)
            {
               perror("Client: Error creating socket.");
            }
            else
            {
					
               /****************************/			
               /* Connect to parent socket */
               /****************************/

               cntd = connect (client_sd,
                               (struct sockaddr_in *)&server, 
                               sizeof (struct sockaddr_in) );
               if (cntd == -1)
               {

                  perror("Client: Error connecting to Server");
                  printf("\n%i\n",errno);

               }
               else
               {
							
                  /***************************************************/
                  /* Test Writability of Socket for up to 2 Seconds. */
                  /***************************************************/

                  FD_ZERO (&writemask);		
                  FD_SET (client_sd, &writemask);

                  selectability = select (FD_SETSIZE,
                                          &readmask,
                                          &writemask,
                                          &exceptmask,
                                          &timeout);

                  if (selectability > 0)

                  {

                     if FD_ISSET (client_sd, &writemask)
                     {

                        /*************************/
                        /* Write data to socket. */
                        /*************************/
											
                        output_cnt = send (client_sd, 
                                           buf_out, 
                                           sizeof(buf_out),
                                           0);

                       if (output_cnt == -1)
                       {

                          perror("Client: Error sending data.");

                       }
                       else
                       {

/*                          sprintf(print_buf_1, "Client: Output buffer transmitted.");*/
							
                       };   /* End Send  Confirmation. */

                     };   /* End Writability Check. */

                  }
                  else if (selectability == 0)
                  {
                  
                     printf ("\n\n\Select Timeout.\n\n");
                  
                  }
                  else
                  {
                     printf ("\n\n\Select Failure.\n\n");
                    
						};   /* End Select Confirmation */

               };   /* End Connect Confirmation. */
					
               /****************/
               /* Close Socket */
               /****************/ 
               
               close (client_sd);
               cntd = 1;
						
            };   /* End Socket Create Confirmation. */
							
            /**********************/
            /* Intermessage Delay */
            /**********************/

            delta_microseconds = 0;

            unix_call_status = gettimeofday
                               (&previous_time, 
                                &system_time_zone);

            while (delta_microseconds < 30000)
            {
            
               unix_call_status = gettimeofday
                                  (&current_time, 
                                   &system_time_zone);


               delta_seconds = current_time.tv_sec
                             - previous_time.tv_sec;

               delta_microseconds = current_time.tv_usec
                                   - previous_time.tv_usec;

               if (delta_seconds < 5)
               {

                  delta_microseconds = (delta_seconds*1000000) 
                                      + delta_microseconds;
               };

             };

         };   /* End Transmission Loop. */
					
      };   /* End Remote Host conditional. */
		
   };   /* End Local Host conditional. */
		
   printf ("\n\n\Client: Terminating.\n\n");
   perror("Errno is ");
   exit (0);

}




John Thier
GE Defense Systems Division
Pittsfield MA
thier@orcad2.dnet.ge.com