How to wait on different events simultaneously - java

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.

Related

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.

Should I close my socket after every successful message handle?

I am writing a program that has a Java Server/Client socket. There will be many messages sent back and forth, and in some situations, sending a message to the server and waiting for a period of time until the server has sent back a "execute" message.
Here is what I have planned:
1 Server (machine could possibly have antivirus security on it)
3 Clients (with room for more clients in future)
Parallel and Interleaved synchronization being carried out on the server side based up the clients output to the server.
When all machines are ready (in sync), when parallel all clients will be sent an "execute" message, when interleave clients will be sent an "execute" command in sequential order 1 by 1
I have started to build the program to have this setup above, and once a message is received on the server, the servers performs actions based upon the input and then sends back a message to the client. I have had problems in the past where messages were not sent or received properly, so my question is:
Do I keep the socket alive until then end of my program?
Or do I keep the socket open only until a successful transmission (a full handshake) has taken place and then close the socket? Leaving the client to connect again next time it wants to send a message.
You should certainly keep TCP connections open for as long as possible, but be prepared to create a new one on failure. You will need to use read timeouts at both ends to detect those.
Q: Should I open a new socket each connection, or keep it around and re-use it for subsequent connections?
A: "It depends".
I would encourage you to "Keep it Simple" and simply open new socket as needed ... until you find that you need otherwise.
By all means: keep the socket open for as long as you reasonably expect a "dialog" between your client and server. Don't force the client to establish a new connection if he's likely to want to talk again reasonably quickly.
Finally, take a look at these links regarding "Connection Pooling":
http://www.javacodegeeks.com/2013/08/simple-and-lightweight-pool-implementation.html
http://tutorials.jenkov.com/java-multithreaded-servers/thread-pooled-server.html
Whether or not you close the socket after a message depends on the protocol that you use between the server and the clients. Probably you define this yourself.
What is probably more important, is that you are able to serve multiple clients in parallel. Therefore, you need to start a separate thread for every client that requests a connection.
Personally, I made some applications with socket communication. To prevent keeping resources for too long when they are not used, but also not closing and reopening constantly when a connection is heavily used, I added a connection supervisor. This is yet another thread, that does is started when a connection is opened, and just performs a countdown from a predefined value (e.g. countdown from 60, decreqsing the value every second for a supervision time of 1 minute). When the counter reaches zero, order to close the socket, and terminate that particular thread.
When a socket is open, and receives a new message, then reset the supervision counter, so the socket will remain open, as long as the time between messages is less than 1 minute.

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.

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.

Categories