Hi all,

I'm new to sockets programming and this board, but I've learned a lot just by
browsing.

I wrote the below code. All I'm trying to do is read from PASSTHRU or INST,
and pass one to the other. port[INST] is already up and running, as is
port[PASSTHRU],hiowever port[PASSTHRU].clientSocket is only set when I get
accept() from port[PASSTHRU].

I can telnet to my server port fine, but if my server sends data from PASSTHRU
to INST, and gets a response like

Afg67 Cre.+ c

then telnet only gets something like this

fg67 Cr+c

so some characters are missing. If I print the hex values RIGHT BEFORE I SENT
it to the PASSTHRU.clientSocket socket, everything looks okay.

I believe I set-up my serial device properly (INST) and my server ip port
properly (PASSTHRU), however maybe not since I'm new to this.

clientSocket is init to -1, which is why I check that value to see if this is
the first time it's connected.

Part of the problem is I know sleep(1) helps a lot, but I'm not allowed to do
that. I need a proprietary close-sourced application to connect to my
PASSTHRU socket and not even know I'm there! Thus, any artificial delays are
bad. I can fiddle with artificial delays but there must be a better way...

Anyway, here is the code I think it relevant. Any help is greatly appreciated,
as I've been fiddling with this all day and I'm getting very discouraged. I'm
using RH 7.x with the 2.4.18-14 kernel is it matters.

Any help or hints or good jokes are GREATLY APPRECIATED!

Josh


Code:


/* this will tell start_listening whether clientSocket
exists on PASSTHRU socket */
volatile sig_atomic_t passthruActive = 0;


start_listening(...)

   unsigned int passthruClientLen;
   int maxfd = (port[REMORA].fd) + 1;
   int i, a, k, p;
   char input;
   int select_value;
   char head[4096];
   char tempbuf[4096];
   int num_bytes;
   fd_set    watchset;
   struct timeval loopdelay;
   FILE*  comm_file;
   
   ...

      /* all sockets are open, confirmed via netstat -l and can telnet no problem... */

      while (TRUE)
      {
         strcpy(tempbuf, "");
         strcpy(head, "");
         .
	 .
	 .
	 loopdelay.tv_sec = 0; //SELECTDELAY;
         loopdelay.tv_usec = 0; /* must reset this for each call - select diddles it */
         FD_ZERO(&watchset);    /* clear all bits in this set */
         FD_SET(port[INST].fd, &watchset);     /* watch our data instrument */
         FD_SET(port[PASSTHRU].fd, &watchset); /* watch the passthru */

	 if ((select_value = select(maxfd, &watchset, NULL, NULL, &loopdelay)) > 0)
         {
	    if (FD_ISSET(port[PASSTHRU].fd, &watchset))
            {
               /* we received something from our passthru */
	       /* this should only happen upon the first connection */

               /* first set our flag that passthru has priority until released */
               passthruActive = 1;

               if (port[PASSTHRU].clientSocket == -1)
               {
                  /* this is our first client connection */

                  /* Set the size of the in-out parameter */
                  passthruClientLen = sizeof(port[PASSTHRU].clientAddress);

                  /* we've received data from the passthru port */
                  if ((port[PASSTHRU].clientSocket = accept(port[PASSTHRU].fd,
                                          (struct sockaddr *) &port[PASSTHRU].clientAddress,
                                          &passthruClientLen)) < 0)
                  {
                     ;//logger(logfile, "ERROR -- 9  We could not accept the call from the passthru socket");
                  } /* end if accept... */
                  else
                  {
	             /* now that we've accepted the connection, listen */
	             FD_SET(port[PASSTHRU].clientSocket, &watchset);

	             /* must increase maxfd to listen to new client socket */
	             if (port[PASSTHRU].clientSocket >= maxfd)
	             {
                        maxfd = port[PASSTHRU].clientSocket + 1;
	             } /* end if */

	             /* now read from new client socket */
	             num_bytes = read(port[PASSTHRU].clientSocket, head, port[PASSTHRU].size - (port[PASSTHRU].buf_idx + 1));

	             if (num_bytes > 0)
	             {
	                strncpy(tempbuf, head, num_bytes);
	                tempbuf[num_bytes] = 0x00; //add NULL
			//tempbuf is only so I can printf for debugging, actuallly send head
		        send_passthru_data_to_modem(head, port[INST].fd);
	             } /* end if */

	             else
	             {
	                /* we couldn't find any data on client socket?? */
		        ;
	             } /* end else */

                  } /* end else we could accept() */

               } /* end if clientSocket == -1 */

               else
               {
	          /* we've been here before, client is waiting... */
	          /* now read from new client socket */
	          num_bytes = read(port[PASSTHRU].clientSocket, head, port[PASSTHRU].size - (port[PASSTHRU].buf_idx + 1));

	          if (num_bytes > 0)
	          {
	             strncpy(tempbuf, head, num_bytes);
	             tempbuf[num_bytes] = 0x00; //add NULL
                     //tempbuf is only for debugging via printf....actually send head
                     /* our client socket was previously established */
                     send_passthru_data_to_modem(head, port[INST].fd);

                  } /* end if */

               } /* end else */

            } /* end if PASSTHRU */


            if (FD_ISSET(port[INST].fd, &watchset))
            {
               /* we're told something is waiting from the data device */
               num_bytes = read(port[INST].fd, head, port[INST].size - (port[INST].buf_idx - 1));

	       /* see if we have any data to read */
               if (num_bytes > 0)
               {
                  strncpy(tempbuf, head, num_bytes);
	          tempbuf[num_bytes] = 0x00; //add NULL

	          /* test to see if must transfer the data untouched, or we can modify it */
	          if (passthruActive == 1)
                  {
                     /* passthru is active, so just send whatever modem sent us */
                     /* back out thru passthru */
                     for (a = 0; a < strlen(tempbuf); a++)
		     {
			printf("[%i]:%i ", a, tempbuf[a]);
		     }
		     printf("  TO PASTHRU:\n%s\n", tempbuf);
		     //tempbuf looks good dangit!! send head, which should be just like tempbuf wo/NULL
                     send_modem_data_to_passthru(head, port[PASSTHRU].clientSocket);
                  } /* end if passthruActive */

	          else if (passthruActive == 0)
	          {
	             /* write the data we received to our traffic file */
		     ;

	          } /* end else if passthruActive == 0 */

	          else
	          {
                     /* passthruActive is neither 0 nor 1, which should never happen!! */
                     ;
                  } /* end else */

               } /* end if num_bytes > 0 */

            } /* end if FD_ISSET [INST] */

         } /* end if select */

      } /* end while loop */

   } /* end init_data_device() loop */

   else
   {
      logger(logfile, "ERROR -- 8 We could not initialize our data device");
      return (FALSE);
   } /* end else if data device returned FALSE */

   return (TRUE);

} /* end listening(...) */





int send_passthru_data_to_modem(char *input_buffer, int modem_fd)
{
   tcdrain(modem_fd);
   /* take everything we got from the passthru socket and give it to modem */
   return (write(modem_fd, input_buffer, sizeof(input_buffer)));

} /* end send_passthru_data_to_modem(...) */

int send_modem_data_to_passthru(char *input_buffer, int passthruSocket)
{
   tcdrain(psthruSocket);
   return (write(passthruSocket, input_buffer, sizeof(input_buffer)));
} /* end send_modem_data_to_passthru(...) */