Multithreaded server design issues...

I’m developing a server that has to be able to cope with several (hundreds) clients simultainiousely. Each connection is 100% autonomous (hard word to spell) and there are no “shared resources”.

My first, basic implementation was a straight-forward approach following the guidlines from sun’s tutorials.

The following code is executed in a separate thread, serving a certain port. I have totally 5 different ports running on the serve, hence 5 threads each serving their individual ports;


ServerSocketChannel ssc = ServerSocketChannel.open();
InetSocketAddress isa = new InetSocketAddress(port);
ssc.socket().bind(isa);

while(true)
{
  SocketChannel sc = ssc.accept();

  if (sc != null)
  {
     Service serviceInstance = (Service)service.newInstance();

     serviceInstance.setSocketChannel(sc);
     serviceInstance.start();
  }
}

Service refers to my own abstract class, designed to deal with this typical thread’s (port’s) behaivour.

So far, so good but since I wanted several clients to be able to connect to the server in parallell (if there is such a thing…), I modified my “serviceInstance” to start a seperate thread to handle its client.

Now this is where it starts to get boring - Suddenly my the SocketChannel closes (stocastically - sometimes it work, sometimes it throws an exception since it closed and I try to read / write to / from it)

Can this be (it seems to but I ask just to get you advice & tips’n’tricks) due to the fact that I use threads? Why does the channel suddenly drop dead?

I think that what I really am looking for in this thread is Your thought of a better approach to solve my problem;

Designing a Java server that has 5 different port open for connections with 5 completely different behaivours, built to cope with at least a couple of hundre clients…

I feel that I’m having trouble to describe my problem correctly, but I hope you understand my situation - sort of :wink:

Thanx / Markus

[quote]I’m developing a server that has to be able to cope with several (hundreds) clients simultainiousely. Each connection is 100% autonomous (hard word to spell) and there are no “shared resources”.
[/quote]
May I suggest using NIO? :slight_smile: It’s likely to be less painful to write and maintain.

Here’s where I get confused. Can you describe more detail about what you mean by connecting in parallel?

I can’t figure out why you would need to start a separate thread inside serviceInstance - you are already creating one thread-per-connection by creating a new serviceInstance instance upon each connect, so what do you need any MORE thread(s) for?

Very short answer :): Three selectors: one each for ACCEPTing new connections, READing data from any connetion, and WRITEing data to any connection. You register 5 server socket channels, one for each port, and then everything will be handled centrally.

Alternatively, if you want to make the distinction between the 5 different sockets more extreme, you could use 11 selectors:

[] One for accepting from any of the 5 ssc’s
[
] 5 for READing from each of the 5 ports
[*] 5 for WRITEing to each of the 5 ports

The accepting Selector knows which port an accept is taking place on, and creates a new SocketChannel which it registers with the appropriate one of the 5 readers (or writers, if your protocol involves the server sending something to the client first of all).

Each of the reader / writer selectors merely needs a reference to it’s companion writer / reader, and can ignore the other 8 readers and writers.

This would be very simple to maintain, but I don’t really know what you’re trying to do, so it may be completely inappropriate :frowning:

Well… In parallel might not have been the best word but I simply mean that while client A is being served, client B and C has to be allowed to connect “at the same time” as A finishes up it’s session.

Therefore, each port’s main-service-thread (the one that a posted earlier) should have to make a new thread for each connected client so that it can serve even more clients, right? And it’s when I do this, that the the SocketChannels decide to die on me :frowning:

About nio - I honestly don’t know enough about it - YET :wink: If you have some good examples / links / tutorials I’m all ears! I’ve been reading a bit about the Selector and all that but I havn’t really got the the point where I can say “Ahhh - now I get it” :wink:

/Markus

!!! (blahblahblah thinks: “I take it you mean “Socket”'s here, not SocketChannel’s, since the latter ONLY work with NIO.”, and then realises he misread the original code).

You ARE using NIO. This may be why it’s not working as you expect :). When you mentioned the Sun tutorial (I haven’t yet read any Sun tutorials for NIO) I think a combination of too much work, too little sleep helped me misread your post to think you were using thread-per-connection, and old-IO.

The typical way with IO is to

[]Socket blah = serversocket.accept();
[
]Create a new object to handle that socket (usually using “new”)
[]…either pass the object the Socket, or more often just use the Socket as one of the arguments to the constructor…
[
]call start() on the object ( which normally is a method that looks like this:


public void start()
{
 Thread t = new Thread( this );
 t.start();
}

…and of course your object must have a “public void run()” method, as defined by the Runnable interface.

Note that anything with the word “Channel” in it means, automatically, that you are using NIO. Apologies for me confusing the issue :slight_smile: - can you copy/paste the URL of the particular Sun tutorial you were following? I didn’t realise there were any NIO tuts from Sun yet…

http://grexengine.com/sections/people/adam/nio/Introduction_to_NIO_Networking.html

I suggest you read through those three articles, and you may find you understand NIO enough to use it (I’ve had a couple of emails from people who said that) - HOWEVER, they aren’t complete, and have lots of bits I’ve changed in the latest revision (not available yet), so you may well still not quite know what to do.

The updated version will appear on JGO.org (this site) - nudge ChrisM :slight_smile: - but until then you can use the link above which is OK (just not as up to date nor as detailed).

I really like your tutorial :slight_smile:
And among your articles I found a link to an research paper about SEDA.
Very useful and interesting stuff :smiley: