I've got a program that opens N sockets to a server, each one in a different thread.
After sending two string for login porpuse, the program listen to the server, until an error occurs and the server sends the disconnect command, and the socket is closed. I want the program to reconnect once the server closes the socket : is it possible?
SocketList.add(new ConnectionHandler(id, actualSocket, out, in));
SocketRead p = new SocketRead(in, out, rowid);
new Thread(p).start();
I'd like that, when the socketread object receive the "DISCONNECT" command, the socket is restarts ( if needed, opening another thread).
I'm not sure what SocketList, ConnectionHandler or SocketRead are, so I'll assume they are classes that you've written for your application.
If you want to be able to reconnect, then you are going to have to change the structure of your code. On the one hand, the SocketRead object doesn't have the information needed to allow it to reconnect. On the other hand, the controlling code (your snippet) isn't able to detect the disconnect command.
It is not clear what will work best, but here are a couple of options:
pass the Socket (or the InetAddress and port number) to SocketRead and make it responsible for opening a new socket.
pass the Thread to the ConnectionHandler and make it responsible for detecting the death of the thread, creation of a new Socket and creating a new Thread.
pass the ConnectionHandler to the SocketRead object, hand have the latter call a callback or event handler method in the former when the socket disconnect occurs.
In the event handler of the DISCONNECT event, put in your reconnection logic.
For more information on how to write EventHandlers refer this link.
Related
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.
I have a Swing client which has a connect and cancel button so it can attempt connection to the server or end a current connection. I'm trying to make it so the client can connect to the server, end the connection and then connect to the server again multiple times.
My understanding is that typically when a client and server end a connection regardless of who ends it the client closes its streams and socket. Obviously then, they cannot be reused for another connection attempt. Right now I have the Socket and stream vars as private instance variables and a method for connecting to server which creates a new socket and then methods for opening and closing streams.
Just wondering how something like this could be typically handled. I've thought about having one humongous method which creates new socket, streams and handles all communication and closing of streams and socket, but it seems messy. Or maybe having a new thread create everything and then when the communication is over terminate the thread.
Ideas appreciated.
- Create a separate Thread at the Server end, when the Client connects to the Server.
- Do the process of read and writing onto the client socket for that particular client into that particular thread.
- And then terminate the Client thread when its done.
- If you again try to connect it, a new thread will span.
- You can always create a HashMap to keep tab on Client-Socket to Thread relation.
You should put all the "logic" in a new class, different than the GUI.
Then because you have 2 buttons, your Gui class should be able to call at least 2 methods on the logic class : connect() and disconnect(). Then in these methods you can handle all the work that is required to connect to a server, open/close streams etc...
That will make your code more clear, more maintainable, and maybe more evolutive if you plan to add features.
I would prefer create a thread for each socket creation and handle request and response withing that thread.
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.
I create a chatting program. My server has a button , the button is for starting the server call accept() method on server socket , button for closing the server call close() on server socket.
When I re-press start button to re-accept connection on the same socket , accept method throws SocketException Socket is closed.
You cannot reopen a socket. If you want to use the variable again, you'll have to create and assign a new socket.
From the Java Documentation on Socket, see info on "close"-method:
Once a socket has been closed, it is not available for further networking use (i.e. can't be reconnected or rebound). A new socket needs to be created.
Closing this socket will also close the socket's InputStream and OutputStream.
If your previous socket was successfully closed, than there should not be problems with re-instantiating that socket. This would work in Java because the JVM will free the garbage for you.
If you want multiple connections to the server (this could be useful since you're making a chat), then keep this in mind.
The accept function, on the server side, will create a new socket every time it's requested. So you can just use threads and pass the new socket (the one created using the accept) to the thread.
If this does not answer your question I would encourage you to go over the Oracle website: http://docs.oracle.com/javase/tutorial/
and to re-formulate the question.
How can I detect when a java socket (client socket or server socket) is closed & execute a callback method when close event occurs?
I don't want to use exception handling to do this. I'm seeking for a solution such as event handler or callback method, something like this(this is just an imaginary code!) :
Socket s = new Socket(ip, port);
s.addSocketClosedHandler(new SocketClosedHandler(){
#Override
public void onSocketClosed(SocketClosedEvent e){
...
}
});
Do you want to handle the event that you close the socket or the event that 'the other side' closes the socket? In the first case, you could subclass Socket and add handlers called when you call 'close'.
In the latter case, the problem is that this is not automatically detected and that reliably detecting it can be difficult and depends on the protocol being used to communicate over the socket. See e.g. this SO question. In general you will have to take action to determine whether the socket has in fact been closed by the other side. If so, you will need to take action. Whatever action you take, you could make sure it also calls callback handlers you registered for that action.
Why can't you use exception handling? This is the way the API is designed.
The only other way to do this is to design your protocol so that the other side sends something before it is about to close so that a local call to close() can be made first - but this won't always work, such as if the connection is closed unexpectedly.