I have an 2-dimensional array to send over the socket
The client is implemented so that it has 2 threads, one for rendering the swing gui and one for RECEIVING the data from server.
The server is implemented so that it has 2 threads, one for listening to incoming request and then put the request to another thread for processing the request (communicating with client)
Once the client interact with the swing gui, data will be constructed and sent to the server (actually, send to the thread which is in charge of processing the particular client), the server then processes the data and send back to client with a new data in an 2-dimensional array with updated information. The client can use the array to render the view.
However, when the first time the client send data, it ok, everything is fine. But the next time, client send new data, but it still receive the old one (server data is still updating)
I dont know if the problem is with the socket itself or the thread.
If you are using Serialization, see the Javadoc for ObjectOutputStream.reset() and ObjectOutputStream.writeUnshared().
Related
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.
I want to write a chat application in Java using Swing as an interface.
I have come up with an idea (with the help of MadProgrammer), but I am not sure whether it is the best way to go about this.
There are two Blockinqueue queues in the main Thread, one for incoming messages and one for outgoing messages.
There are four threads, two for outgoing and two for incoming messages, one each to handle the GUI and the socket.
Threads for outgoing messages:
ActionListener (Swing): Is triggered when user clicks "send" in GUI. The thread adds the new message to the Outgoing Queue and triggers notifyAll() on it.
socketOutgoing: Has access to socket. Sleeps, with wait() on Outgoing Queue, until it is notified. Sends new messages in Outgoing Queue through socket, then goes back to sleep again.
Threads for incoming messages:
socketIncoming: Has access to socket. Checks continuously for new
message in socket (how?). When there is a new message, adds it to
the Outgoing Queue and triggers notifyAll() on it.
Swingworker displayIncoming: Sleeps, with wait() on Incoming Queue, until it is notified. Displays new messages in GUI, then goes back to sleep again.
While this would theoretically work, it seems a bit messy (and unreliable) to have four threads for this.
Is there a more practical solution?
Note to future readers: My description of socketIncoming was misguided: It is not possible to "check continuously for new message in socket".
When you call ObjectInputStream#readObject(), and there is no new message, it simply waits, or "blocks", until a new messages arrives. There is no way to check beforehand whether a new message has arrived. See this question.
If I was thinking about doing something like I would probably set up two queues, an outgoing and incoming queue. These would be used to "stage" messages.
The idea being that outgoing messages would be placed into the outgoing queue and when Thread was able to, it would pop off the next message and send it. When the queue was empty, it would simply "wait" until a new message become available.
The concept would work in reverse for the incoming queue. The Thread would read a message and push it onto the incoming queue.
Some other process (possibly a SwingWorker) would be monitoring the queue and pop the next message of it and re-sync it with the GUI.
You might find Concurrency in Swing of some use.
How the underlying protocol actually worked would dictate a lot more of the details though
for a simple chat application you shall have two parts
Client part
Server part.
Now, you have to decide which protocol you want to use for your communication [Tcp] or [Udp]. Though your message transmission should be reliable so you have to use java Tcp ServerSocket. your server will be multi-threaded means for each client connect with server will have separate thread to handle all message communication from that client.
For Client side, it will have GUI componenet and one dedicated thread to receive message from server. when you want to send message to any user, just pass the message and send through client socket.
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.
I am testing the behaviour of some client software, and need to write some software that emulates router-like functionality, preferably using something simple like UDP sockets. All it needs to do is receive the packet, alter the time to live, and send it back. Is this possible in regular Java? Or do you do something like the following:
Listen on Socket A
For EACH udp packet received, open a NEW socket, set time to live on that socket, and send it back (or this isn't possible/efficient?)
Receiver gets packet with altered values that appear like it has traversed some hops (but in reality hasn't)
So two approaches may be possible - editing the recieved packet directly (and then simply sending back), or constructing a new packet, copying the values from the original one and setting the appropriate headers/socket options before sending it out.
EDIT: the 'router' does not do any complex routing at all such as forwarding to other routers... it is simply decrements the t-t-l header field of the received message and sends the message directly back to the client.
Please refer API of Socket and ServerSocket class. Most of the server implementation for variety of protocols does accept packets at standard port like 80 and send response using some ephemaral port.
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.