Creating a multi-user TCP server

Discussion in 'Java' started by jamesgoode, Apr 4, 2008.

  1. jamesgoode

    jamesgoode Guest

    Hi,

    I'm trying to create a multi-user TCP server, without the use of a
    thread-per-connection model. My plan is to create an instance of the
    ClientConnection class, which is stored in an array, for each
    connection. A 'connection listener' thread handles this. The inputs
    from the clients are then handled in a loop, which looks like this:

    while (true)
    {

    for (int i = 0; i < MAX_CONNECTIONS; i++)
    {
    try {
    if (connections!=null)
    if (connections.in.ready())
    connections.out.writeBytes(connections.in.readLine()+"\n
    \r");
    } catch (IOException e) {
    // TODO Auto-generated catch block
    connections = null;
    }
    }

    }

    (connections.in is a BufferedReader)

    The problem is, that BufferedReader.ready() always seems to return
    true, and that BufferedReader.readLine() halts the program until there
    is a line to read.

    All help is greatly appreciated.

    Many thanks,

    --James.
     
    jamesgoode, Apr 4, 2008
    #1
    1. Advertising

  2. jamesgoode wrote:
    > Hi,
    >
    > I'm trying to create a multi-user TCP server, without the use of a
    > thread-per-connection model. My plan is to create an instance of the
    > ClientConnection class, which is stored in an array, for each
    > connection. A 'connection listener' thread handles this. The inputs
    > from the clients are then handled in a loop, which looks like this:
    >
    > while (true)
    > {
    >
    > for (int i = 0; i < MAX_CONNECTIONS; i++)
    > {
    > try {
    > if (connections!=null)
    > if (connections.in.ready())
    > connections.out.writeBytes(connections.in.readLine()+"\n
    > \r");
    > } catch (IOException e) {
    > // TODO Auto-generated catch block
    > connections = null;
    > }
    > }
    >
    > }
    >
    > (connections.in is a BufferedReader)
    >
    > The problem is, that BufferedReader.ready() always seems to return
    > true, and that BufferedReader.readLine() halts the program until there
    > is a line to read.
    >
    > All help is greatly appreciated.
    >
    > Many thanks,
    >
    > --James.


    BufferedReader.readLine() blocks until a line terminator is found in the
    stream. That is going to be inconvenient for what you have planned. I
    think it would be possible to check BufferedReader.ready() in a loop and
    read a single char from the stream until ready() returns false, then
    move on to your next stream. I don't see anything in the docs that
    suggest that ready() will always return true like
    InputStream.available() does. One advantage to this method is that it
    should scale well with a ThreadPoolExecutor to a lot of connections.

    Depending on what sort of latency you can tolerate you might be able to
    just block on a read and set a short timeout. Or the other option is to
    use NIO and its non-blocking features.

    Are you sure that you are going to have so many simultaneous connections
    that the thread per connection will be a problem? For a small number of
    connections (less than 50 on a Windows machine) it is very easy to code.

    --

    Knute Johnson
    email s/nospam/linux/

    --
    Posted via NewsDemon.com - Premium Uncensored Newsgroup Service
    ------->>>>>>http://www.NewsDem
     
    Knute Johnson, Apr 5, 2008
    #2
    1. Advertising

  3. jamesgoode

    jamesgoode Guest

    On Apr 5, 12:34 am, Knute Johnson <>
    wrote:
    > jamesgoode wrote:
    > > Hi,

    >
    > > I'm trying to create a multi-user TCP server, without the use of a
    > > thread-per-connection model. My plan is to create an instance of the
    > > ClientConnection class, which is stored in an array, for each
    > > connection. A 'connection listener' thread handles this. The inputs
    > > from the clients are then handled in a loop, which looks like this:

    >
    > > while (true)
    > > {

    >
    > > for (int i = 0; i < MAX_CONNECTIONS; i++)
    > > {
    > > try {
    > > if (connections!=null)
    > > if (connections.in.ready())
    > > connections.out.writeBytes(connections.in.readLine()+"\n
    > > \r");
    > > } catch (IOException e) {
    > > // TODO Auto-generated catch block
    > > connections = null;
    > > }
    > > }

    >
    > > }

    >
    > > (connections.in is a BufferedReader)

    >
    > > The problem is, that BufferedReader.ready() always seems to return
    > > true, and that BufferedReader.readLine() halts the program until there
    > > is a line to read.

    >
    > > All help is greatly appreciated.

    >
    > > Many thanks,

    >
    > > --James.

    >
    > BufferedReader.readLine() blocks until a line terminator is found in the
    > stream. That is going to be inconvenient for what you have planned. I
    > think it would be possible to check BufferedReader.ready() in a loop and
    > read a single char from the stream until ready() returns false, then
    > move on to your next stream. I don't see anything in the docs that
    > suggest that ready() will always return true like
    > InputStream.available() does. One advantage to this method is that it
    > should scale well with a ThreadPoolExecutor to a lot of connections.
    >
    > Depending on what sort of latency you can tolerate you might be able to
    > just block on a read and set a short timeout. Or the other option is to
    > use NIO and its non-blocking features.
    >
    > Are you sure that you are going to have so many simultaneous connections
    > that the thread per connection will be a problem? For a small number of
    > connections (less than 50 on a Windows machine) it is very easy to code.
    >
    > --
    >
    > Knute Johnson
    > email s/nospam/linux/
    >
    > --
    > Posted via NewsDemon.com - Premium Uncensored Newsgroup Service
    > ------->>>>>>http://www.NewsDem


    Thanks for your help,

    I'll try what you've suggested, and incorporate it into the
    ClientConnection class (just to make it easier).

    I'll post back soon with results, and anything else that I'll have
    found.

    --James.
     
    jamesgoode, Apr 5, 2008
    #3
  4. jamesgoode

    Christian Guest

    jamesgoode schrieb:
    > Hi,
    >
    > I'm trying to create a multi-user TCP server, without the use of a
    > thread-per-connection model.


    I would recommend you to look a bit more into non Blocking IO .. there
    is no way around this if you really don't want one Thread per Connection .

    So you are gonna need to use a selector. And for Transforming bytes to
    chars you have to use a Char(En/De)Coder.

    For starting I found that rather intresting:
    http://www.exampledepot.com/egs/java.nio/NbServer.html?l=rel

    also the links on the page help with the other stuff involved in non
    blocking IO.


    Christian
     
    Christian, Apr 5, 2008
    #4
  5. jamesgoode

    EJP Guest

    Knute Johnson wrote:
    > jamesgoode wrote:
    >> The problem is, that BufferedReader.ready() always seems to return
    >> true, and that BufferedReader.readLine() halts the program until there
    >> is a line to read.

    >
    > BufferedReader.readLine() blocks until a line terminator is found in the
    > stream. That is going to be inconvenient for what you have planned. I
    > think it would be possible to check BufferedReader.ready() in a loop and
    > read a single char from the stream until ready() returns false, then
    > move on to your next stream. I don't see anything in the docs that
    > suggest that ready() will always return true like
    > InputStream.available() does.


    Err, it doesn't return 'true', it returns an integer >= 0, which can
    always be zero according to the contract, and always is e.g. in the case
    of an SSLSocket. All that 'ready()' does ultimately is to return 'true'
    if there is buffered data in the BufferedReader or available() > 0.

    However there is no reason why ready() == true should mean there is an
    entire line waiting to be read. So your readLine() can block.

    So I would either overcome your phobia about threads, which are OK in
    units of hundreds or so, or use NIO if you know you are going to have
    tens or hundreds of thousands of connections. Mostly the blocking
    threads arising out of normal use of java.net are doing nothing except
    block.
     
    EJP, Apr 6, 2008
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John Grandy
    Replies:
    0
    Views:
    645
    John Grandy
    Sep 13, 2005
  2. Tiger
    Replies:
    5
    Views:
    1,011
    Dave Thompson
    May 1, 2006
  3. Jeff
    Replies:
    19
    Views:
    601
    Kathryn Van Stone
    Sep 5, 2007
  4. John Salerno
    Replies:
    10
    Views:
    496
    John Salerno
    Jun 16, 2008
  5. Ross

    Creating IIS Login to SQL Server in multi-tier app

    Ross, Nov 6, 2004, in forum: ASP .Net Web Services
    Replies:
    1
    Views:
    155
    Dino Chiesa [Microsoft]
    Nov 8, 2004
Loading...

Share This Page