Network programming

Discussion in 'Java' started by SS, Jan 15, 2004.

  1. SS

    SS Guest

    Has anyone come across this before:

    I am pacing out a load of traffic from multiple clients to a
    multi-threaded server (one thread/client), and back again.

    As I add more clients, at some point I *think* I reach the limitation
    of the network bandwidth. Anyway, at this point the server and clients
    all eventually enter OutputStream.write() (where the OutputStream is
    the stream attached to the relevant socket) and never return. No
    exceptions are thrown either, and everything just sits there.

    Each client is only active while it sends a specific amount of data
    (eg. 10MB), then it ceases execution. I would have thought therefore,
    that if the bandwidth limit was passed, the individual transmission
    speeds would be reduced until clients start to finished their
    transmissions and the bandwidth would be regained. The transmissions
    should be ultimately successful, assuming the network buffers were not
    flooded (in which case I would expect an exception from write()).

    But, it never finishes, no matter how long I leave it.

    If I then start to kill individual clients, exceptions are thrown in
    the server as the sockets are closed, and these exceptions can be seen
    to come from OutputStream.write(), indicating that the server had
    entered write(), and never left until the client died.

    It seems to me like write() should either throw an exception or return
    pretty much immediately, but it does neither, therefore locking up the
    server.

    Anyone know what this problem is?

    Thanks a lot,
    SS


    It's a Linux platform btw, using Kaffe and Sun VMs and Sun compiler.
     
    SS, Jan 15, 2004
    #1
    1. Advertising

  2. SS

    Pat Ryan Guest

    I'm no expert, but it sounds like it could be a buffer deadlock - a call to
    write to a socket will block if the write buffer is full. So if reading and
    writing happen in the same thread, and both client and server are blocked on
    a write, that would be a deadlock...

    "SS" <> wrote in message
    news:...
    > Has anyone come across this before:
    >
    > I am pacing out a load of traffic from multiple clients to a
    > multi-threaded server (one thread/client), and back again.
    >
    > As I add more clients, at some point I *think* I reach the limitation
    > of the network bandwidth. Anyway, at this point the server and clients
    > all eventually enter OutputStream.write() (where the OutputStream is
    > the stream attached to the relevant socket) and never return. No
    > exceptions are thrown either, and everything just sits there.
    >
    > Each client is only active while it sends a specific amount of data
    > (eg. 10MB), then it ceases execution. I would have thought therefore,
    > that if the bandwidth limit was passed, the individual transmission
    > speeds would be reduced until clients start to finished their
    > transmissions and the bandwidth would be regained. The transmissions
    > should be ultimately successful, assuming the network buffers were not
    > flooded (in which case I would expect an exception from write()).
    >
    > But, it never finishes, no matter how long I leave it.
    >
    > If I then start to kill individual clients, exceptions are thrown in
    > the server as the sockets are closed, and these exceptions can be seen
    > to come from OutputStream.write(), indicating that the server had
    > entered write(), and never left until the client died.
    >
    > It seems to me like write() should either throw an exception or return
    > pretty much immediately, but it does neither, therefore locking up the
    > server.
    >
    > Anyone know what this problem is?
    >
    > Thanks a lot,
    > SS
    >
    >
    > It's a Linux platform btw, using Kaffe and Sun VMs and Sun compiler.
     
    Pat Ryan, Jan 15, 2004
    #2
    1. Advertising

  3. SS

    SS Guest

    "Pat Ryan" <> wrote in message news:<4006fb24$>...
    > I'm no expert, but it sounds like it could be a buffer deadlock - a call to
    > write to a socket will block if the write buffer is full. So if reading and
    > writing happen in the same thread, and both client and server are blocked on
    > a write, that would be a deadlock...
    >
    > "SS" <> wrote in message
    > news:...
    > > Has anyone come across this before:
    > >
    > > I am pacing out a load of traffic from multiple clients to a
    > > multi-threaded server (one thread/client), and back again.
    > >
    > > As I add more clients, at some point I *think* I reach the limitation
    > > of the network bandwidth. Anyway, at this point the server and clients
    > > all eventually enter OutputStream.write() (where the OutputStream is
    > > the stream attached to the relevant socket) and never return. No
    > > exceptions are thrown either, and everything just sits there.
    > >
    > > Each client is only active while it sends a specific amount of data
    > > (eg. 10MB), then it ceases execution. I would have thought therefore,
    > > that if the bandwidth limit was passed, the individual transmission
    > > speeds would be reduced until clients start to finished their
    > > transmissions and the bandwidth would be regained. The transmissions
    > > should be ultimately successful, assuming the network buffers were not
    > > flooded (in which case I would expect an exception from write()).
    > >
    > > But, it never finishes, no matter how long I leave it.
    > >
    > > If I then start to kill individual clients, exceptions are thrown in
    > > the server as the sockets are closed, and these exceptions can be seen
    > > to come from OutputStream.write(), indicating that the server had
    > > entered write(), and never left until the client died.
    > >
    > > It seems to me like write() should either throw an exception or return
    > > pretty much immediately, but it does neither, therefore locking up the
    > > server.
    > >
    > > Anyone know what this problem is?
    > >
    > > Thanks a lot,
    > > SS
    > >
    > >
    > > It's a Linux platform btw, using Kaffe and Sun VMs and Sun compiler.



    Yeah, that sounds about right. I was assuming that if the write buffer
    was full then I'd get an IOException from write(), but if indeed it
    does block then deadlock would occur as you described, which is what
    seems to be happening.
    Thanks for your help.
    SS
     
    SS, Jan 16, 2004
    #3
  4. SS

    SS Guest

    "Pat Ryan" <> wrote in message news:<4006fb24$>...
    > I'm no expert, but it sounds like it could be a buffer deadlock - a call to
    > write to a socket will block if the write buffer is full. So if reading and
    > writing happen in the same thread, and both client and server are blocked on
    > a write, that would be a deadlock...
    >


    Ok, so this leads me to another problem then.
    Basically I need write() to be non-blocking. You can make read()
    non-blocking using setSoTimeout(), but it doesn't seem to affect
    write().

    For example, suppose I am streaming data from a server to a client,
    and the client for some reason stops reading, but leaves the socket
    open.
    The server eventually fills the write buffers, then gets stuck in
    write().
    I would want to be able to throw away any data that could not be
    written and timeout the server if write failure occurs for some period
    of time.
    However, as long as the client is alive, this is impossible because
    control of the server is never passed back from write().

    Anyone have any ideas on this?

    Thanks a lot.
     
    SS, Jan 16, 2004
    #4
  5. SS

    BarryNL Guest

    SS wrote:
    > "Pat Ryan" <> wrote in message news:<4006fb24$>...
    >
    >>I'm no expert, but it sounds like it could be a buffer deadlock - a call to
    >>write to a socket will block if the write buffer is full. So if reading and
    >>writing happen in the same thread, and both client and server are blocked on
    >>a write, that would be a deadlock...
    >>

    >
    >
    > Ok, so this leads me to another problem then.
    > Basically I need write() to be non-blocking. You can make read()
    > non-blocking using setSoTimeout(), but it doesn't seem to affect
    > write().
    >
    > For example, suppose I am streaming data from a server to a client,
    > and the client for some reason stops reading, but leaves the socket
    > open.
    > The server eventually fills the write buffers, then gets stuck in
    > write().
    > I would want to be able to throw away any data that could not be
    > written and timeout the server if write failure occurs for some period
    > of time.
    > However, as long as the client is alive, this is impossible because
    > control of the server is never passed back from write().
    >
    > Anyone have any ideas on this?
    >
    > Thanks a lot.


    It's been a while since I played with this, but I seem to remember that
    the java.nio.channels.SocketChannel class can do this.
     
    BarryNL, Jan 16, 2004
    #5
  6. SS wrote:

    > Basically I need write() to be non-blocking. You can make read()
    > non-blocking using setSoTimeout(), but it doesn't seem to affect
    > write().


    Switch to UDP ?
     
    Thomas Schodt, Jan 16, 2004
    #6
  7. SS wrote:

    >
    >
    > Ok, so this leads me to another problem then.
    > Basically I need write() to be non-blocking. You can make read()
    > non-blocking using setSoTimeout(), but it doesn't seem to affect
    > write().
    >
    > For example, suppose I am streaming data from a server to a client,
    > and the client for some reason stops reading, but leaves the socket
    > open.
    > The server eventually fills the write buffers, then gets stuck in
    > write().
    > I would want to be able to throw away any data that could not be
    > written and timeout the server if write failure occurs for some period
    > of time.
    > However, as long as the client is alive, this is impossible because
    > control of the server is never passed back from write().
    >
    > Anyone have any ideas on this?
    >
    > Thanks a lot.


    Implement your own FIFO with a size limit that throws and Exception or
    just discards the excess (your choice). The FIFO needs to be
    synchronized and needs to block read() calls when empty.

    Start a thread that loops reading the FIFO and writing the socket. It
    will spend most of its time blocked in either read() or write().

    Now just write to the FIFO rather than direct to the socket.

    Steve
     
    Steve Horsley, Jan 16, 2004
    #7
  8. SS

    SS Guest

    Thomas Schodt <"news0401"@\"xenoc.demon.co.uk\"> wrote in message news:<bu8q4g$h16$1$>...
    > SS wrote:
    >
    > > Basically I need write() to be non-blocking. You can make read()
    > > non-blocking using setSoTimeout(), but it doesn't seem to affect
    > > write().

    >
    > Switch to UDP ?


    Can't do that unfortunately - the idea is to test a TCP connection
    under stress conditions.
    I'm surprised at this blocking limitation - I will have a go with
    java.nio.channels.SocketChannel though...
     
    SS, Jan 16, 2004
    #8
  9. SS

    SS Guest

    > Implement your own FIFO with a size limit that throws and Exception or
    > just discards the excess (your choice). The FIFO needs to be
    > synchronized and needs to block read() calls when empty.
    >
    > Start a thread that loops reading the FIFO and writing the socket. It
    > will spend most of its time blocked in either read() or write().
    >
    > Now just write to the FIFO rather than direct to the socket.
    >
    > Steve


    I'm not sure that I completely understand you, but it doesn't seem
    like it will make any difference to me. You could use a queue to pace
    out data I suppose - is that what you are implying?

    However the socket has effectively got an unknown bandwidth because it
    depends on the performance of the client. I want to know if I can
    write to the socket or not, so I really need an indication of whether
    the buffers are full or not. The whole point is not to end up blocking
    in write().

    I had a look at SocketChannel and this does actually seem to do what I
    want (albeit in a somewhat obtuse way), however unfortunately it only
    exists in version 1.4, and I am stuck with version 1.3!

    I'm still surprised at the functionality of write(). By always
    blocking there is always the possibility that the server could stall
    forever if the client fails to read() and remains connected - which is
    completely unacceptable.

    Has nobody come accross this problem themselves?

    Cheers,
    SS
     
    SS, Jan 19, 2004
    #9
    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. Kal
    Replies:
    1
    Views:
    9,534
    Kevin Spencer
    Jun 21, 2004
  2. Jane Davis

    Network Service account over network

    Jane Davis, Jun 22, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    454
    Kevin Spencer
    Jun 22, 2005
  3. Bill Volk
    Replies:
    1
    Views:
    3,155
    Bill Volk
    Jul 2, 2003
  4. kin
    Replies:
    0
    Views:
    922
  5. king
    Replies:
    1
    Views:
    287
Loading...

Share This Page