SocketChannel.write() in a single thread processing multiple clients - java

my application has a queue with " outgoing network packets" (A POJO with a ByteBuffer and a SocketChannel) inside, consumed by a single thread that writes the data to the SocketChannel.
I do this to guarantee that every client that should receive packets, gets its turn. This means that SocketChannel.write() writes sequentially to multiple clients (= 1 at a time).
Can anyone tell me what could go wrong working like this? The SocketChannels are created from a ServerSocketChannel, so they're blocking.
I fear that the write() operation could block for 1 client, making the other clients wait...

The write() operation can indeed block in blocking mode. If you want fairness and single threading you will have to use non-blocking mode.

If a client socket fails to consume all the data in one write (non-blocking), you could close the client. This will only happen when the buffer fills, so you could increase the send buffer of the socket to a level where you are comfortable doing this.

Related

How to wait on different events simultaneously

I have an open socket connection to a server.
On the one hand, in my code, I want to wait on a BlockingQueue for a message to be handed to me for sending to that server, then write it to the OutputStream.
When I send such a message, this normally expects an answer from the server (which needs to be read from the InputStream).
At the same time, I want to continuously listen on the socket's InputStream for spontaneous incoming messages from the server (server generated events).
Is there a recommended pattern for handling such a situation?
I obviously expect to have at least 2 threads involved (waiting on the two inputs - BlockingQueue and Socket). Any pointers are welcome on how to sync those, links to docs/blogs welcome.

Scenario in multi-threaded socket communication

I have socket client application, during application startup the socket is created(connection established with server) and it starts two threads which run in parallel.
Thread-1: continuously reads the socket using read method (blocks until data is received)
Thread-2: continuously writes the data.
While writing the socket, if thread-2 receives IO exception, then it discards the existing socket and creates new socket and starts communication. Since thread-2 discards the socket, the thread-1 receives null pointer exception.
Do we have any strategy to handle this
Thread 2 needs to shutdown the socket for input before closing it. That will cause thread to receive and end of stream, which should cause it to close the socket and exit. Then thread 2 can create another socket and start another read thread.
You are beginning to encounter the problems associated with the proactor style of system design. Solving this problem requires some communication between the two threads. Choosing what this communication is is where it gets messy. It has to be something that stops thread1 from trying to read the socket. I'm not so good with Java, but in C, this means using a signal.
I suggest you avoid signals, even if there is an equivalent in Java.
One better option is to have thread1 blocked on a call to select() (or whatever the Java equivalent is), waiting on the socket and on a pipe. Thread2 writes to the pipe when it wants to close the socket, thread1 returns from select(), writes a response to thread2 down the pipe, and calls select() again but only on the pipe. Thread2 reads that response, closes the socket, opens a new one, sends something else down the pipe to wake up thread1 again, which can now go back to select() but this time on the pipe and the new socket. This achieves an execution rendezvous between thread1 and thread2; thread2 can close the old socket and open a new one because it knows (via the pipe communication) when thread1 is not using the socket.
This is somewhat messy. And also becoming more like the reactor design pattern. In which case one may as well simply have just one thread that uses select() to choose whether to read the socket as part of whatever loop it is executing. This single thread would be reading data when it is available, not doing a blocking read in the hope that data arrives. If something goes wrong with a socket write and the socket needs to be replaced, it simply does so; there's no other thread to sync with. Assuming your socket is connected to a remote server on a network (rather than a service on the same machine), the speed of the Ethernet will still be the dominant bottleneck; reactor style systems are no slower.
In general, dealing with network failures is far easier with the reactor systems style, because you don't have threads committed to carrying out actions that other threads know to be inappropriate. Unfortunately, most programming environments are proactor, eg Windows, Boost ASIO, RabbitMQ, etc. Proactor systems are fine until something goes wrong, after which it is often necessary to throw the whole process away because it can easily become insanely complicated for the programmer to sort out all the borked callbacks and async IOs.
One option is to use ZeroMQ if you can. This requires you to be using ZeroMQ everywhere (server too), but it makes it far easier to deal with network problems. It is a reactor, not a proactor.

thread safety of concurrent read and write on a socket

A tcp socket is an endpoint which has bidirectional read and write capabilities. In java we can aquire InputStream and OutputStream of the Socket.
is it safe to use those streams concurrently?
As far as i know there is a single connection that is capable to send or recieve from one endpoint to other data at any given time.
I'm implementing nio transport layer based on SocketChannels, and i want to keep one thread for all writes and one thread for accepting and reads, but i'm not sure what will happen if my threads concurrently try to read and write at the same time on the same socket...
As far as I know there is a single connection that is capable to send or recieve from one endpoint to other data at any given time.
Or both at the same time. It's a full-duplex connection. You can send and receive at the same time.

Must a listening socket runs in thread?

I have some problems understanding how a socket should be handled. I get that server socket must runs in its own thread, because it must check if there are new connections. Now, i'm not sure if every socket opened by a new connection should runs in a thread.
What i have in mind is checking every x time the socket states. If it has something to be read, then read. If not, check the next socket. I see some examples where this process is done in a thread, but i dont want a socket to do stuff, just want to read if it has some data, and process them.
The answer is no, you don't need to listen in a separate thread. But, just realize that while you are "listening" your entire program will be waiting for that to complete before moving onward.
So unless you are fine with your entire program waiting, I would suggest a separate thread.
You can also have one thread which communicates with all sockets in a round-robin manner. It checks each socket if it has new data, and when it hasn't it checks the next.
Another alternative is to use NIO (New Input/Output).
The idea behind NIO is that you have a thread with one Selector which owns multiple Channels (a channel can be a network socket or any other IO interface). You then call selector.select() in a loop. This method blocks until one or more channels have data, and then returns a set of these channels. You can then process the data the channels delivered.
Here is a tutorial.
The problems with round-robin using available() are many.
It assumes that available() actually works, which isn't guaranteed.
It assumes that all clients need the same amount of service.
N-1 clients wait while one client is serviced.
A non-responsive client can block not only your application but all the other clients.
I'm sure there are more.
Don't do this. Use threads or NIO.

Listener for incoming messages

I am currently trying to create a chat application using the Socket and ServerSocket classes, but i kinda ran into a roadblock. I need some kind of listener to execute a certain block of code when a message is incoming from the server or the client, but i can't seem to find one. An option would of course be to just check for incoming messages every 10 ms or something, but isn't there a smarter solution?
In general, you should assign a Thread to each Socket you are reading, so that Thread can block on the socket and wait for incoming information.
You should take a look at DataFetcher: http://tus.svn.sourceforge.net/viewvc/tus/tjacobs/io/
This class can work asynchronously, and notify a FetcherListener when new data is available
I recommend Netty or Mina. As for Socket and ServerSocket, the read() calls are blocked, so in a way the code below the read()s are executed whenever there's incoming data.
Beware of the incomplete message though, because Sockets provide a stream of bytes and the applications are usually more comfortable with discrete messages.

Categories