![]() |
| | #1 |
| Registered User Join Date: Jun 2003
Posts: 41
| 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 myPASSTHRU 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(...) */
|
| registering is offline | |
| | #2 |
| Registered User Join Date: Jun 2003
Posts: 41
| I don't know if it helps, but it seems like if I send a <CR> thru telnet, the serial device behaves as if I sent two <CR>. This makes me think the serial port is echoing stuff, but as far as I know I turned all of that off. How I configured the serial port (INST) is below. The ip socket (PASSTHRU) is very standard (socket using AP_INET, SOCK_STREAM, IPPROTO_TCP...). Since some chars seem missing on returning to the clientSocket (telnet as a test), I tried to turn off every blocking or delay feature..... Code:
/ **************************************************
Procedure: open_client_serial_port(...)
Purpose: Attempts to open the serial port passed-in as parameter 'port'
Returns: int: 1 if the serial device could not be opened
Notes: This might also 'exit' and not just 'return' if we could not open our
serial device!
**************************************************/
int open_client_serial_port(comm_data_t* port,
const comm_connection_t* environment,
FILE* logfile)
{
int retval = 0; /* our return value */
port->fd = open(port->dev, O_RDWR | O_NOCTTY | O_NDELAY);
if (port->fd < 0)
{
logger(logfile, "ERROR -- 2 Could not open our serial device");
perror(port->dev);
retval = 1;
port->comm_status = COMM_DOWN;
}
else
{
/* we could open our serial port */
logger(logfile," -- Debug: 2 Successfully opened our serial device");
tcgetattr(port->fd,&port->ser_oldtio); // save the current modem setting so we can restore them
tcgetattr(port->fd,&port->ser_newtio); // save the current modem settings to the new settings structure
cfmakeraw(&port->ser_newtio); // set struct for new term settings to raw. See man 'cfmakeraw'
port->ser_newtio.c_cflag &= ~CRTSCTS; // make sure rts/cts flow control is turned off
port->ser_newtio.c_cflag |= (CLOCAL | CREAD); // make sure receiver is enabled and port owner not changed
port->ser_newtio.c_iflag &= ~(ISIG | IXON | IXOFF | IXANY);// make sure software flow control is off
cfsetispeed(&port->ser_newtio, B9600); // set the input baudrate for new terminal settings
cfsetospeed(&port->ser_newtio, B9600); // set the output baudrate for new terminal settings
tcgetattr(1,&port->ser_old_stdout_tio); // we gotta do this - there is a Linux bug
tcsetattr(1,TCSANOW,&port->ser_newtio); // make stdout settings like modem settings
tcgetattr(0,&port->ser_oldstdtio); // get stdin settings for restoration ...
tcgetattr(0,&port->ser_newstdtio); // ... and use them as a basis for changes
port->ser_newstdtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make them raw
tcflush(port->fd, TCIOFLUSH); // clear the input and output port buffers
tcsetattr(0,TCSANOW,&port->ser_newstdtio); // set the new attributes immediately
tcsetattr(port->fd,TCSANOW,&port->ser_newtio); // set the new attributes for the serial port immediately
port->comm_status = COMM_OK; //we really need some error checing on all of the above calls ...
}
if (port->fd < 0)
{
logger(logfile, "ERROR -- 2b Could not open our serial device");
perror(port->dev);
exit(-1);
}
//set the serial port to return immediately after a read
fcntl(port->fd, F_SETFL, O_NONBLOCK);
return(retval);
} /* end open_client_serial_port */
|
| registering is offline | |
| | #3 |
| Registered User Join Date: Jun 2003
Posts: 41
| Oops, what a dumb mistake! Thanks for the second pair of eyes, I really appreciate it. |
| registering is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| server client application - (i really need your help) | sarahnetworking | C Programming | 3 | 03-01-2008 10:54 PM |
| Socket Programming Problem!!!! | bobthebullet990 | Networking/Device Communication | 2 | 02-21-2008 07:36 PM |
| Where's the EPIPE signal? | marc.andrysco | Networking/Device Communication | 0 | 12-23-2006 08:04 PM |
| Unicode vurses Non Unicode client server application with winsock2 query? | dp_76 | Networking/Device Communication | 0 | 05-16-2005 07:26 AM |
| Server Client Messaging Program | X PaYnE X | Networking/Device Communication | 3 | 01-04-2004 05:20 PM |