Scenario in multi-threaded socket communication - java

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.

Related

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.

Is dataInputStream of a Socket know how to deal with multiple writings to it?

I am developing a Net game, in general:
I have a server which launch a serverThread for each client that has connected to it.
Its purpose is to listen to messages from the specific client and to process it on the server.
Also for each client that is opened it launch a clientThread which is a listening thread to messages from the server.
The two threads are quite simple and similar threads which implements the Runnable Interface and therefore override the run method.
Each Run method is some kind of infinite loop that has on its start the command (blocking command):
int command = m_In.readInt();
and then do a process by switch cases structure over the received command.
after process was done, the loop cause the code to return to the blocking m_In.readInt()
To wait for another command to come.
My question is: My Net game has enough options which are using the communication over this m_In, so what happens if there are two messages or more coming almost together to the clientThread, how would the dataInputStream will act?
Will it begin to process first message and after its done will grab the second which is on some kind of a queue? or it could drop the second message and it will be lost?
Maybe that stream has buffer so it stores the second message in a queue or something?
Thanks
Streams by their nature expect data to come in a specified order. If you have two threads writing to the same stream at the same time, bad things will happen.
Now you can certainly synchronize access to the stream and have the two thread interleave their writing (so long as you build some sort of formatting on the stream that tells the receiver how to read data), but you don't get this by default.
Typically though, each client thread would have their own connection and thus their own stream to write into. A server can obviously read from multiple streams at the 'same time', and that is the normal server pattern.

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

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.

Monitoring and killing blocked threads in Java

In a servlet-based app I'm currently writing we have separate thread classes for readers and writers. Data is transmitted from a writer to multiple readers by using LinkedBlockingQueue<byte[]>, so a reader safely blocks if there is no new data to get from the writer. The problem is that if remote clients served by these reader threads terminate connection, Tomcat won't throw a broken pipe unless the writer sends in new data and attempts to transmit this new chunk to the remote clients. In other words, the following attack can be performed against our service:
Start a streaming write request and don't write any data to it at all.
Keep creating and dropping read connections. Since the writer doesn't produce any data, reading threads attached to it remain blocked and consume memory and other resources.
Observe the server run out of RAM quickly.
Should I create a single maintenance thread that would monitor sockets belonging to blocked reader threads and send interrupt() to those that appear to have lost connection to their respective clients? Are there any major flaws in the architecture described above? Thank you.
Sounds to me that the vulnerability lies in the fact that your readers wait forever, regardless of the state of the incoming connection (which, of course, you can't know about).
Thus a straightforward way to address this, if appropriate, would be to use the poll method on BlockingQueue, rather than take.Calling poll allows you to specify a timeout, after which the reader will return null if no data has been added to the queue.
In this way the readers won't stay blocked forever, and should relatively quickly fall back into the normal processing loop, allowing their resources to be freed as appropriate.
(This isn't a panacea of course; while the timeout is still running, the readers will consume resources. But ultimately a server with finite resources will have some vulnerability to a DDOS attack - and this reduces its impact to a customisably small window, instead of leaving your server permanently crippled, at least.)
The approach I taken in the past is to have blocking connections and only have reader threads. When you want to write to multiple connections, you do that in the current thread. If you are concerned about a write blocking for every, you can have a single monitoring thread which closes blocked connections.
You can still have resources tied up in unused sockets, but I would have another thread which finds unused sockets and closes them.
This leaves you will one thread per connection, plus a couple of monitoring threads.

implementing keepalives with Java

I am building a client-server application where I have to implement a keepalive mechanism in order to detect that the client has crashed or not. I have separate threads on both client and server side. the client thread sends a "ping" then sleeps for 3 seconds, while the server reads the BufferedInputStream and checks whether ping is received, if so it makes the ping counter equals zero, else it increments the counter by +1, the server thread then sleeps for 3 seconds, if the ping counter reaches 3, it declares the client as dead.
The problem is that when the server reads the input stream, its a blocking call, and it blocks until the next ping is received, irrespective of how delayed it is, so the server never detects a missed ping.
any suggestions, so that I can read the current value of the stream and it doesn't block if there is nothing on the incoming stream.
Thanks,
Java 1.4 introduced the idea of non-blocking I/O, represented by the java.nio package. This is probably what you need.
See this tutorial for how to use non-blocking I/O.
Also, assuming this isn't homework or a learning exercise, then I recommend using a more robust protocol framework such as Apache Mina or JBoss Netty, rather than building this stuff from scratch. See this comparison between them, and why you'd want to use them.
You can have a separate monitoring thread which monitors all the blocking connections. When a connection receives anything it can reset a counter. (I would treat any packet as good as a heartbeat) Your monitoring thread can increment this counter each times it runs and when it reaches a limit (i.e. because it wasn't reset back to zero) you can close the connection. You only need one such thread. The thread which is blocking on the connection you just closed with throw an IOException, waking the thread.
On the other side, a heartbeat can be triggered whenever a packet has not been sent for some period of time. This mean a busy connection doesn't send any heartbeats, it shouldn't need to.

Categories