HZNM.COM
welcome to my space
X
Search:  
 HOME   sockets: off by a few chars between server/client
sockets: off by a few chars between server/client
Published by: anonym 2009-01-09
Welcome to:hznm.com

  • C server client program "Cannot bind socket" after being run 10 ::
    8 posts - 4 authors - Last post: Feb 23C server client program "Cannot bind socket" after being run 10 times Programming int main(int argc, char** argv) { char data[1024];
    http://ubuntuforums.org/showthread.php?t=704600
    HOME
    Hi all,

    First off, this board is awesome so thanks to anyone and everyone who
    takes the time to read my novel. :)

    I wrote the below code. All I'm trying to do is read from PASSTHRU or INST,
    and pass data from one to the other. port[INST] is already up and running,
    as is port[PASSTHRU], however 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, it sends something like

    Afg67 Cre.+ c

    but 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. However since
    sometimes chars from telnet to server are repeated and some are missing in
    the other direction, maybe I didn't set up my ip port (PASSTHRU) or my serial
    port (INST) properly, and some sort of control chars are being intermixed?

    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...

    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 is 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.

    Thanks so much in advance.

    Josh







    /* 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%sn", 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(...) */




    / **************************************************
    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 */


  • Thank you so much! The sizeof is definitely an error, what a dumb mistake. Your reading of my
    code is correct with the clientSocket also, however that's because I didn't post my entire code.
    What I actually do at the top of the loop, is something like

    if (port[PASSTHRU].clientSocket != -1)
    {
    /* we've got a client so listen to them */
    FD_SET(port[PASSTHRU].clientSocket, &watchset);
    }

    That way once we know someone's there we start looking to see if anything's readable. There's
    probably a more elegant way of doing this too, but the sizeof error is most probably the bulk
    of my error for now.


  • Your main problem lies in these two functions:


    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(...) */


    You don't want to use sizeof(input_buffer), there... That will
    return whatever your native pointer size is (most likely 4 bytes)...
    Because, you're dealing with a char* at this point, not a real
    buffer, anymore...

    What you need to do is change the functions to take another
    arg: the length to send... Then, change your calls to pass in
    the length you got from your read()'s... (You could actually
    do the sizeof() on the real buffers there, and have it work, but
    you don't want to do that... Otherwise, you'd be writing tons of
    useless junk that you never actually read into the buffer... You
    already know the exact length of the data to send, because you
    just read it...)

    Also, I think your select() logic is a bit wacky... Namely, you
    don't add the "port[PASSTHRU].clientSocket" FD to the fd_set
    if it's already been filled in (you've already done an accept()),
    which I think you want to... You add it immediately after the
    accept(), but then at the top of the loop, you clear out the fd_set,
    so that doesn't accomplish anything... You need to add it at
    the top of the loop, where you add the other 2 FDs... Also, it
    looks like you're only trying to read from that accept()'d
    "clientSocket" if your listening socket selects as readable yet
    again... (Or, else, I'm just not following the curly braces clearly,
    or something...)





  • How much does getting a small tattoo on your hip/stomach hurt?
    Do anyone else have an itchy anus? ?

    You are looking at:hznm.com's sockets: off by a few chars between server/client, click hznm.com to home
  • wht dos the new psp ver 4 01 feature coz my vers is 3 95 and i want 2 knw if the new version lets me play iso
  • i need help with my flag quilt
  • how do you become invulnerable in cod4 online multiplayer
  • how do i email yahoo games about their pinochle game
  • form which website can i downlaod the latest grand theft auto
  • what happens if you win the lottery in california
  • anyone wanna partner up for army of 2 ps3 us version
  • how do you make a macro for hunter 039 s mount for world of warcraft wrath of the lich king
  • marriage on harvest moon ioh have all bachelors and bachelorettes on island red heart blue feather etc
  • which one is better nintendo ds or sony psp
  • cant access music picture and video file on my psp
  • how can i have to windows open internet and one for my online game bf2
  • is my deck of tournament status
  • what happened to yugioh cards
  •  
  • can anyone tell me all the games in this video
  • fall out boy plush dolls
  • are you allowed to have someone take a photo of you at a poker table at a casino
  • im trying to build a yugioh warrior deck can you help
  • do you know the name of this child 039 s toy
  • what sims game is the best for playstation and why
  • which is best cricket game ea sports 2007 or brian lara intl cricket 2007
  • someone plz where to watch max payne free online full movie
  • bad company or far cry 2 ps3
  • where can you buy a plain sand green lego torso
  • is a zombie deck in yugioh powerful
  • i want revenge for fun
  • 为什么我玩warcraft 3过了一下就蓝屏
  •  Homepage | Add to favorites | Contact us | Exchange links | LOGIN | Site map | 
    Copyright© 2008 hznm.com        Site made:CFZ