Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Sockets vs SocketChannels ?

 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This post is like a bottle tossed to the sea, because everybody here seems to choose RMI against
sockets ...
Anyway, Max writes in his book (p. 290) :

As of spring 2002, most versions of the SCJD exam explicitly require that either sockets or RMI be used as the networking protocol in your project implementation. This is a firm requirement, meaning that thos adventurous souls who decide to deviate from this requirement may fail automatically upon submission. For this reason, we suggest that you do not use SocketChannels unless your exam instructions state clearly that a SocketChannel implementation is permitted.

That statement, put together with other parts of his book where it appears that NIO may be used for file IO (confirmed by many posts on this forum) may be summed up in this java pseudocode :

(fileIO == fileNIO) ? feelFreeToChoose() : assert(false)
(networkIO == networkNIO) ? assert(false) : (networkIOChoosen() ? passed() : failed())

I don't see how to justify it. Are SocketChannels really forbidden ? What do you think ?
The reason behind that question is this : Following Max's advice, I used plain sockets and I have nearly finished with it. As I wanted to ensure some scalability (a minimum !) to my network framework, I implemented a client connections queue ("dormant" connections) allocated to threads taken out of a pool of threads. I see two main advantages to that design :
  • handlers reuse (the threads in the pool) : starting a new thread consumes a lot of CPU cycles
  • connections persistency : Any "State" or "session" information may be encapsulated within the ClientConnection - no need for a cookie or other sort of client identification -, and as the server "knows" its clients, it can talk to them : an example of this could be broadcasting a message and a funny (but user-friendly) example of this example could be a smooth port number change ).


  • A ConnectionHandler thread dequeues a ClientConnection (or waits till notified if the queue is empty), and processes the ClientConnection if needed. I'll come back to this "if needed" in a moment. If no network IOException of some sort occurs while processing the ClientConnection (or if there was nothing to process), it's simply reenqueued. Else it is not, meaning that the client will get a SocketException of some sort, forcing it to come back "by the main door" if it decides so.
    Now the "... and processes the ClientConnection if needed". Giving that reads on plain sockets are blocking and that ConnectionHandler threads cannot spend time having nothing to do with a given connection, I set client connections SO_TIMEOUT to its mimnimm value (1) and ConnectionHandlers stop reading when they get a SocketTimeoutException. If offset in the buffer read is still 0, there is nothing to process, else the object sent by the client is built from the bytes received. Warning to anybody who would be tempted by this design : you may get a SocketTimeoutException in the middle of the read !! (my tests show that) in which case you get an EOFException in ObjectInputStream.readObject() : the issue is easy to circumvent but you must be aware of it.
    But now that everything works fine, I find it so poor in comparison with real multiplexing (SocketChannels). It leads me to think of this car metaphor :
  • You are shown two cars : a Volkswagen (Socket) and a Ferrari (SocketChannel).
  • You are told that you must choose the Volkswagen.
  • So you "choose" it, but as you like speed cars, you do a hard work on the Volkwagen engine to speed it up, knowing that it will still be far slower despite your efforts.
  • And you know that in the real world (you are a very rich guy ) you wouldn't have hesitate between them at all.


  • What would you do in my place ?
    Keep it as it is (1) or refactor and use SocketChannels (2) ? And if you think (1), do you see some hidden issues out there that I didn't take into account ?
    Thank you in advance,
    Best,
    Phil.
    [ September 01, 2003: Message edited by: Philippe Maquet ]
     
    Andrew Monkhouse
    author and jackaroo
    Marshal Commander
    Pie
    Posts: 12014
    220
    C++ Firefox Browser IntelliJ IDE Java Mac Oracle
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi Phil,
    Since reading this, I have been arguing with myself as to whether this might be allowable or not.
    I have gone back to the instructions, and what I have is:
    You must use either serialized objects over a simple socket connection, or RMI

    Now I guess the question is what is a "simple socket"?
    Any client trying to connect to your server would just see a socket connection to which it can send / receive serialized objects. So from that perspective it looks OK. It is not as though you are providing an enhanced communication protocol.
    But from a coding perspective, a simple socket is probably a Socket(). Anything else is probably a more involved socket.
    From Sun/Prometric perspective, it makes sense to specify that you must use just the Socket() class. It means that the examiner's only have to know the one API, and it gives you the challenge of handling all the issues you have mentioned (people doing RMI get other challenges).
    Going back to the car metaphor - yes, you are rich enough to buy the Ferrari, but you might choose not to because you will only be driving it around town with it's 40km speed limits, and because of the extra taxes / insurance you will have to pay. (I actually know a guy who sold his Porsche and bought a BMW because he was attracting too much attention from his local police ). So it is not just a question of what is the most powerful - your solution still has to meet the other requirements: in this case the "simple" socket requirement.
    My feeling is that you should stick with the Socket() solution. But as you can tell, I am not 100% convinced SocketChannels are forbidden.
    Regards, Andrew
    [ September 01, 2003: Message edited by: Andrew Monkhouse ]
     
    Philippe Maquet
    Bartender
    Posts: 1872
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi Andrew,

    I have gone back to the instructions, and what I have is:
    quote:
    --------------------------------------------------------------------------------
    You must use either serialized objects over a simple socket connection, or RMI
    --------------------------------------------------------------------------------
    Now I guess the question is what is a "simple socket"?

    How could I miss that "simple" word ?! Reading it, I feel that "simple" means something like "basic", probably excluding SocketChannel.
    My feeling is that you should stick with the Socket() solution. But as you can tell, I am not 100% convinced SocketChannels are forbidden.

    You convinced me.
    Thank you.
    Best,
    Phil.
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic