• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Sockets vs SocketChannels ?

 
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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 ]
     
    author and jackaroo
    Posts: 12200
    280
    Mac IntelliJ IDE Firefox Browser Oracle C++ Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • 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
      Number of slices to send:
      Optional 'thank-you' note:
    • 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.
     
    reply
      Bookmark Topic Watch Topic
    • New Topic