Thread: non-blocking keyboard read

  1. #1
    Registered User
    Join Date
    Jun 2006
    Posts
    16

    Post non-blocking keyboard read

    Hi,

    Does anyone know which function/library I should use to be able to read a line of user input without Curse? And once I find this function, the following code structure should be able to pick up the keyboard I/O stream right?

    Code:
    fd_set rset;
    int max_sd=highest_sd++;
    
    while(1) {
     FD_SET(0, &rset);
     if( select(max_sd, &rset, NULL, NULL, NULL) < 0 ) {
      //error code
     }
    
     if( FD_ISSET( 0, &rset ) {
       //a line has been entered, do something useful here
     } else if( FD_ISSET( other_sd, &rset) {....
     } else {
      //error: select() not blocking
     }

    Thanks

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Well it seems like a reasonable start, what sort of effect are you seeing compared to what you expect?

    Also, how are you reading stdin when select says there is data available?

    Did you use setbuf/setvbuf on stdin to make it non-blocking before doing any of this.

    I'm assuming that you're on Linux (or other *IX OS with a proper implementation of select).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jun 2006
    Posts
    16
    Quote Originally Posted by Salem
    Well it seems like a reasonable start, what sort of effect are you seeing compared to what you expect?

    Also, how are you reading stdin when select says there is data available?

    Did you use setbuf/setvbuf on stdin to make it non-blocking before doing any of this.

    I'm assuming that you're on Linux (or other *IX OS with a proper implementation of select).
    I think I got it to work. I'm on linux.

    I'm basically trying to demux socket IO and keyboard IO such that a user can send and receive message at the same time.

    new question:
    Is it possible to block persistent TCP connection until new data arrives? I'm trying to use one connection for all the message exchange between two network sockets, and I want the process to block until new data is available. select() does not seem to be able to block the socket. I dig up the man page and surely enough, select() unblock when a socket is ready for transmission, not when new data is available. Any idea?

    What I have currently is this
    Code:
    sdTCPChild = accept(sdTCP, ...
    
    while(1) {
     FD_SET(sdTCPChild, *rset);
     if( select() .... ) {
     }
    
     if( FD_ISSET( sdTCPChild, &rset) ) {
       //received TCP data, read it, do something useful
       //#1
     }
    }
    What would happen is that the client would establish a connection with the server. But as soon as it sends one piece of data, the server would loop forever through #1 (bypassing select()'s blocking). It would read the data at the first cycle, then read 0 bytes from the pipe afterward.

    Thanks!
    Last edited by pppbigppp; 01-16-2007 at 07:04 AM.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > select() unblock when a socket is ready for transmission, not when new data is available. Any idea?
    Yes, use the correct set.
    select() can operate on input, output and errors. So use the 'write' set to block on a socket until it is ready to send.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Jun 2006
    Posts
    16
    Quote Originally Posted by Salem
    > select() unblock when a socket is ready for transmission, not when new data is available. Any idea?
    Yes, use the correct set.
    select() can operate on input, output and errors. So use the 'write' set to block on a socket until it is ready to send.
    I'm trying to read from a socket.

    READ->DISPLAY;
    KEYBOARD->WRITE(send)

    The problem is that read() blocks the first time, but for some reason it does not block anymore afterward(which is also why select does not block AFTER the first piece of data arrives). So I end up with this
    Code:
    bytesRead = read(sdTCPChild, recBuf, sizeof(recBuf));  //properly blocks until data comes, read non-zero bytes from socket
    bytesRead = read(sdTCPChild, recBuf, sizeof(recBuf));  //does not block, read 0 bytes. ???
    Last edited by pppbigppp; 01-16-2007 at 10:16 AM.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Did you make the sockets themselves non-blocking?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Jun 2006
    Posts
    16
    Quote Originally Posted by Salem
    Did you make the sockets themselves non-blocking?
    I didn't do anything special to the socket. By default it blocks. The first read() works perfectly fine. I think I know what the problem is, but don't know the solution yet. My guess is that the first read() take all the bytes in the socket. Then somehow the second read() only see the EOF character in the socket. So it immediately returns with 0 bytes read. This would also explain why select() won't block. This is not the behaviour I expected though.

    Here is some of the socket initiation code
    Code:
    //omit a bunch of error checking to save space
    sdTCP = socket(PF_INET, SOCK_STREAM, ptrp->p_proto);
    bind(sdTCP, (struct sockaddr *)&sad, sizeof(sad));
    listen(sdTCP, QLEN);
    I had another program that does network data transfer and it works. The major difference is that the program I'm working on is based on persistent TCP connection.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Doesn't 0 mean the socket in question has been closed?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Jun 2006
    Posts
    16
    Quote Originally Posted by Salem
    Doesn't 0 mean the socket in question has been closed?
    Oh my, that was it. There is a rouge close(socket) statement in my client socket write routine(left over from the non-persistent connection design). I didn't notice it for so long cause I kept thinking its server's problem. Now everything make sense again. Select is working just fine

    Thanks a bunch!

  10. #10
    Registered User
    Join Date
    Jun 2006
    Posts
    16
    Follow up question:

    What's the most graceful way to detect broken pipe? Currently, if either the client and the server close() its end of the pipe, select() on the other process will unblock indefinitely and so I end up with infinite loop.

    Is there a function call that checks up on a file descriptor?

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Just a guess, but I said
    select() can operate on input, output and errors.
    If you put your sockets / pipes / whatever into the error set as well, then you should get information as to when the unexpected happens.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. "sorting news" assignment
    By prljavibluzer in forum C Programming
    Replies: 7
    Last Post: 02-06-2008, 06:45 AM
  2. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  3. I am lost on how to read from file and output to file?
    By vicvic2477 in forum C++ Programming
    Replies: 4
    Last Post: 02-27-2005, 11:52 AM
  4. Read Array pro!!Plz help!!
    By Supra in forum C Programming
    Replies: 2
    Last Post: 03-04-2002, 03:49 PM
  5. Help! Can't read decimal number
    By Unregistered in forum C Programming
    Replies: 2
    Last Post: 09-07-2001, 02:09 AM