HI,

I'm trying to write an application in C++ that has two things - a TCP server (listen server) as well as a TCP client where it can send to other TCP servers. I currently have both parts set up simultaneously. I did this by calling fork() and having the listen server begin to listen in the child process and having the parent process prompt the user for input. however, this is where the program hangs. Because I am prompting the user for input via 'cin', its blocking the TCP listen server from receiving any messages.

So, I have a few questions. One, since I called fork(), why would cin block the TCP server? Arent they, in essence, two different programs? Also, is there a way do do a non-blocking 'cin' ? Do you have any other suggestions for other ways to successfully implement this?

Thanks!

I'm not familiar with servers but I if fork is anything like multithreading, it shouldn't affect the other process. As for the cin that doesn't bring your program to a halt, try the "GetAKeySyncState()" function from <windows.h>, but that only tracks key presses; if you play around with it you can take in strings though.

I'm not familiar with servers but I if fork is anything like multithreading, it shouldn't affect the other process. As for the cin that doesn't bring your program to a halt, try the "GetAKeySyncState()" function from <windows.h>, but that only tracks key presses; if you play around with it you can take in strings though.

ahh, im programming in linx environment so i dont thinkt that will help.. thanks though.

Well after 2 minutes of pondering, I came up with an incredibly stupid and overly complicated idea: create another program to write into a .txt document using ostream with cin, save and exit after the input. Then have your client program constantly look for the said .txt document and open the .txt document after the first program creates it. Take the input and delete the .txt document, then call the first program again to take more inputs. Crude I know, but its creative isn't it? :P

Lousy timeout...

You don't actually have to fork(), just poll() or select() on the appropriate channels.

As for cin -- that is, by default, a line-buffered input (meaning, it blocks until the user presses the Enter key).

Making the standard input non-blocking and reading it is not trivial in *nix. A simpler solution would be to poll()/select() on stdin as well, and only block so long as it takes the user to press the Enter key.

Another option would be to fork() a new process whose only purpose is to wait on user input (via cin), and when it is received just to send the input (as a message) to the main process.

If undaunted, you can use tcsetattr() to turn off line buffering. Just be sure to turn it back on before your program terminates or your users will hate you. Also take a look through Understanding UNIX termios VMIN and VTIME

// Warning, I'm not at home at the moment and
// I have not tested this code. As it has been a
// few months since I've done anything like this,
// be warned.

#include <termios.h>
#include <unistd.h>

struct char_buffered
  {
  struct termios initial_settings;

  char_buffered( bool echo = true )
    {
    struct termios settings;
    tcgetattr( STDIN_FILENO, &initial_settings );
    settings = initial_settings;

    // Get one character at a time
    settings.c_cc[ VMIN  ] = 0;
    settings.c_cc[ VTIME ] = 18;

    // Turn off line-editing characters (sorry, got to do it)
    settings.c_lflag &= ~(ICANON | IEXTEN);

    // Turn off character echo?
    if (!echo) settings.c_lflag &= ~(ECHO);

    tcsetattr( STDIN_FILENO, TCSANOW, &settings );
    }

  ~char_buffered()
    {
    // Restore things to normal
    tcsetattr( STDIN_FILENO, TCSANOW, &initial_settings );
    }
  };

To use it, just create an instance of the class.


Oh yeah, don't forget to cin.sync_with_stdio(); .

Whew. Hope this helps.

This article has been dead for over six months. Start a new discussion instead.