multiple InputReader for a single Socket - java

I have a java client/server program using ServerSocket/Socket.
In my client, I have a thread(call in ReceiverThread) which always waits for a incoming message from server. so it will block my InputReader (myInputReader.readObject()) .
In the client, there are also some threads, which send some stuff to the server and wait using (myInputReader.readObject()), until server responses. but in this case, if the server sends a response, there is a chance that the ReceiverThread catches the server response, which is not what i want.
Is there any way that i can have multiple InputStreams in a single Socket connection?
UPDATE: I have to use java Socket

It doesn't make sense to listen on a socket in 2 (or more) different threads simultaneously. What you need to do is have a single "entry point" for incoming data, and have that entry point understand the context of each data block (message) and spread that to what ever logical peace of code uses it. This is a general design pattern, not a java issue.

Related

Java - Recognise sent-to-one and sent-to-all messages from server, on the client-side

I am working on a server/client application that allows multiple clients to be connected to the server at any given time.
For each client, the server sets up a ClientHandler object that has an input and output stream to the client connected at this socket. Through this connection, the client is free to send a number of messages to the server at any point throughout the running of the program, and the server will respond according to the message.
What I need to implement is a mechanism that sends, at certain times, messages to all currently-connected clients. I have done this by storing all the output streams to clients in an ArrayList<PrintWriter> that will allow the same message to be sent to all clients.
What I am struggling with is this:
When a message is received that is individual to the client, the client GUI is updated accordingly (only a select number of messages can be sent, so there only a select number of possible responses-from-server, dealt with by client-side if statements). However, when a message is received by the client that was sent to all clients, I would like the client to update the GUI quite differently.
Considering that both forms of input come from the same input stream, I can see this being difficult, and I anticipate that I will have to declare any methods that cause output using the PrintWriter will have to be made synchronized. However, is there a way to process the different inputs while using the same PrintWriter at all? Would this have to be done using further if statements or could it be done using a separate Thread on the client side that handles messages sent to all clients?
Thanks for any advice, if you think you can help then feel free to ask for parts of my existing code!
Mark
You are first of all lacking a protocol between your server and your clients!
Obviously the server can send two types of messages "response" and "broadcast".
A rather simple approach is tagging your messages: e.g. prefix your mesages with "R" if it is a response to a request and with "B" if it is an unattended broadcast message. (This all depends how communication between server and clients is intended to be performed.)
Whether your client needs different threads for coping with the messages is a completly different story. Having different threads is useful if the processing activity within your client would prevent timely reads of the socket. Then you might consider having an I/O thread that is doing communications and is dispatching the messages to different "handlers" (could be other threads) for processing. (This I/O thread also can remove the tag such that existing processing code need not learn about the lower protocol with the server.)
An analogous reasoning might apply to your server side. Depending on the dynamics of interactions and processing of requests, you might use several threads. Then you should have one that is doing I/O with the clients and others that are doing the work (generating responses or broadcast messages)
When your clients connect to the server, your server creates a Socket for it, here it is Socket socket = ss.accept();, your socket variable will be holding that client.
now if you just keep adding your client socket to a arraylist in your while loop, you will have a list of clients actively connected with your server like:
after the accept:
clients = new ArrayList<DataOutputStream>();
Socket socket = ss.accept();
os = new DataOutputStream(socket.getOutputStream());
clients.add(os);
Now as you have all the clients in that clients arraylist, you can loop through it, or with some protocol define which client should i send the data after reading.

handling multiple constant socket connections simultaneously

I want to write a chat application in java which can handle many users simultaneously. I read about sockets and threadpools to limit thread number, but I can't imagine how to handle e.g. 100 socket connections at the same time and do not create 100 new threads. Idea is that client connects at the beginning and his connection stays opened until he leaves the chat. He can send data to server as well as receive other users messages.
Read from socket is blocking operation, so I would need to check all user's sockets in loop with some timeout if new data is available in particular socket connection? My first idea was to create e.g. 3 threads for handling input from all connected users and 3 threads for outcomming communication from server to clients, but how can I achieve that? Is there any async API for sockets in Java where can I define threadpools for in/out communication?
Make a Client class that extends Thread. Write all the methods and in the void run() method, write the code you want executed when the client connection is made.
On the Server side, listen for new connections. Accept a new connection, get the information about the connection, pass it in the constructor to create a new Client object, and add it to an ArrayList to keep track of all ongoing connections and execute the start() method. So, all the Client objects are in an Arraylist, and the they keep running at the same time.
I had made such a chat application about an year ago. And do not forget to close the connection once the Client disengages, orelse all the objects pile up and slow up the application. I learnt that the hard way.
Use Netty as it provides an NIO framework (non-blocking IO) so that you do not need 1 thread per connection. It is a little bit (or a lot..) more complicated to write a server using non-blocking IO, but there are performance gains in regards to not requiring one thread per connection.
However, 100 threads is not so many, so you could still create your server using standard IO and one thread per connection, it just depends on how much you need to scale.
For a server setup using Netty, you create a channel to which new connections are assigned. This channel is an ordered series of handlers which process incoming (and outgoing) messages from a connection / client. The handlers themselves all need to be asynchronous such that when a handler needs to return a message to the client it writes it asynchronously (non-blockingly) to the channel and receives a future back to which it can attach actions for when the message is actually written.
There is a little bit of a learning curve, but it is not that steep and the overall design of your application will be much better if built the Netty way vs using standard blocking IO.

java socket sending and receiving

since hours I am thinking about how I should use Java Sockets to send and receive data. I hope you can help me finding a good way to do it.
I have build a Server/Client structure where the client connects to the server and gets his own thread handling a request-response method. The information are capsuled in XML.
At the beginning the Server starts a blocking socket read. First I use writeInt() where the lenght of the XML message is transmitted. After that the Server reads the amount of lenght bytes and parses the message. After the transmission the client goes in the receive state and waits for an response.
That is fine but after the client authenticates the server waits for the things that will come and blocks.
But what should I do when the server has no information which needs to be transmitted. I could try to destroy the read blocking and send the message to the client. But what happens if the client comens in mind that he has also a message and also begins to send. In that moment no one will listen.
For that maybe I could use some sort of buffer but I have the feeling that this is not the way I should go.
I have been searching for a while and found some interesting information but I didn't understand them well. Sadly my book is only about this simple socket model.
Maybe I should use two threads. One sending and one receiving. The server has a database where the messages are stored and waiting for transmission. So when the server receives a message he stores that message in the database and also the answer like "message received" would be stored in the database. The sender thread would look if there are new messages and would send "message received" to the client. That approach would not send the answer in millisenconds but I could image that it would work well.
I hope that I gave you enough information about what I am trying. What would you recommend me how to implement that communication?
Thanks
But what should I do when the server has now information which needs to be transmitted.
I would make writes from the server synchronized. This will allow you to respond to requests in one thread, but also send other messages as required by another thread. For the client you can have a separate thread doing the receiving.
A simpler model may be to have two sockets. One socket works as you do now and when you "login" a unique id is sent to the client. At this point the client opens a second connection with a dedicated thread for listening to asynchronous events. It passes the unique id so the server know which client the asynchronous messages are for.
This will give a you a simple synchronous pattern as you have now and a simple asynchronous pattern. The only downside is you have two socket connections and you have co-ordinate them.

Java sockets event driven

I have a client that will connect to a server through a socket. After connecting every event that happens on the server will be sent to all registered clients.
Every client should receive data related to the event.
I just need to implement the client...meaning I need to connect to the server and receive the events' data.
I was thinking on doing something like:
this.socket = new Socket(InetAddress.getByName(host),
this.socket.connect(socket.getLocalSocketAddress(), SOCKET_TIMEOUT);
And then launch a thread which gets the InputStream of the socket in a while loop.
But I don't know if this the best way to implement an event driven client through a socket.
Is it?
In an event driven environment a Datagram Socket will incur lower network overhead but will not give you the reliability. Here is a tutorial about writing datagram socket clients and servers.
This is often done by spawning a separate thread for the client that continuously makes blocking calls to read() from the stream - that way, as soon as data becomes available the read() call unblocks and can act on what it received ('the event fires'), then it goes back to blocking waiting for the next event.
You don't necessarily need a thread here unless the client has to respond to some other input like GUI events.
Then, assuming you are talking about TCP, read from the socket in a loop, buffering received data until you have a complete application "event", and call your application "event handler". It's that simple.

Java multithreaded stateful server - networking design

I'm trying to implement a stateful, multi-client server application and have some questions about the networking/threading design. The problem I'm currently facing is how to exchange messages between the communication layer and the logic layer.
The server handles multiple clients, where each of them can be active in multiple "channels", where each channel has multiple stages and may have multiple clients acting in it. Think of it to something similar as a chat program with multiple rooms.
I have already implemented the receiving of messages on the server side. Each client has his own thread that blockingly reads the data and decodes into a message. Now how to proceed? In my oppinion, each channel should also have this own thread to easily maintain its state. I could use a BlockingQueue to exchange the received messages with the channel thread, who's blockingly waiting for new messages on that queue.
But then how to send messages to the clients? The logic in the channel will handle the message, and produce some messages to be sent to one/some/all of the clients. Is it safe to use the channel thread to directly write to the socket? Or should I use another BlockingQueue to transmit the messages to the client handler thread? But how to wake it then, since it's waiting on the socket to read? Or should I use a separate send-thread per client, or even a separate send-socket?
BTW: I know I could use existing libraries for the networking layer, but I want do do it from scratch on plain sockets.
Put a send message method on the communication object that wraps the socket. Synchronize this method so that only one thread can be calling it at once. Then, it doesn't make any difference how many threads call this method. Each message will only be sent one at a time. You also don't have to disturb the thread that's blocking to read. This send method will be a quick enough operation that you don't have to worry about other threads blocking while a thread sends.
As long as the channel has a reference to the communication objects for each connected client, it can send messages and not worry about it.
If it ever caused problems, you could always modify that send message to enqueue the object to be sent. Then you could have a specific send thread to block on the queue and write the contents to the socket. But from my experience, this won't be necessary.
What about a event mechanism? When you ready with processing the request and there is a data for client available, then simply send it with an event for the client socket handler thread. as because the transmission from client is ended, you can send reply normally - if i think correctly.

Categories

Resources