accept() , close() methods On ServerSocket - java

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.

Related

socket.isConnected() does not detect disconnected socket [duplicate]

This question already has answers here:
Java socket API: How to tell if a connection has been closed?
(9 answers)
Closed 1 year ago.
I have a Java application that connects to a service using a socket. I always expect to receive something from that socket, and if it disconnects I need to reconnect. Reconnect works fine when I close/open socket from remote application side in normal way. But when the remote application is killed, my Java application does not detect that. I run the thread with:
if (socket.isConnected()) { /* code */ }
This function does not detect when the socket is killed. Why? How to detect that remote socket is killed?
Note: I must use java 1.4
UPD
I do reading from socket input stream acording loggic:
if (in.available()) {...}
This not detects socket is disconnected. Should I use in.read() even if no data available to detect closed socket?
The various isXXX() methods of Socket don't track the actual state, but what has been done to the socket. For example isConnected() will return true even after a socket has been closed, if it has been connected at some point.
The only way to detect if a Socket is still valid is to try to use it, i.e. read or write to it. If an exception is thrown, you need to clean up and reconnect.
This function does not detect when the socket is killed. Why?
These functions only tell you the current state of the Socket object: they don't actively test the line. isConnected() means 'have I ever connected?'.
How to detect that remote socket is killed?
You need to read a message from the connection with an appropriate timeout. If the connection is closed or lost you eventually get an IOException, or a timeout will be reached.
BTW To save error messages, I suggest you send a message indicating a graceful disconnect before closing. This way graceful disconnects can be treated differently to connection failures in term of logging.

Closing BufferedWriter/Reader affects other instances bound to the same socket?

I have 'n' server threads, and each one listen to 1 client.
When a server thread receives a message from its client, it needs to notify the other 'n-1' clients, and that's the reason why I keep a shared object (containing an array of 'n' sockets, one for each client) between the server threads.
Moreover, in the main server thread that holds the ServerSocket, every time I accept a new connection with a client I open a BufferedWriter/Reader to give a first answer to him using the new socket returned from ServerSocket.accept().
In case of an "OK" answer I open a new thread passing the new socket to it, in order to listen to the new client's following requests.
The problem is that i cannot close the BufferedReader and the BufferedWriter in the main server thread, because it will also close the underlying stream, causing problems to the server thread that is listening to that socket/stream.
And the question: if I open another BufferedReader (bound to the same socket) in the new thread, and then close it, will other BufferedReaders(Writers) ( specifically the ones opened in the main server thread, that i couldn't close before ) opened on the same socket be closed? Will an exception be thrown on them?
It could be possible to share the opened BufferedReader / Writer instead of the socket, to avoid instantiating every time a new object, but this is a question related to what could happen if i do things in the way described above.
Please tell me if I hadn't been clear, my english is not really good.
Closing any Reader or Writer or stream wrapped around a stream closes the wrapped stream.
Closing either the input stream or the output stream of a socket closes the other stream and the socket.
Closing the socket closes both streams.
In other words closing any of it closes all of it.
As noted in comments, multiple buffered streams/Readers/Writers wrapped around a single stream cannot work.
Multiple threads reading from/writing to the same socket is unlikely to work correctly either, unless you take great care with synchronization and buffering.
You should not do any I/O with an accepted socket in the accept loop. Otherwise you can block, which affects further clients.
You need to rethink your design.
Each Socket with an open connection to another Socket has an open InputStream and an open OutputStream. Closing either one of these streams will also close the socket. Closing a socket or its streams will not affect other sockets unless they are connected. You don't want to close any streams unless you also want to close the connection between the sockets using the streams. Please ask if there is something i missed or if you have other questions :)

What kind of strategy is more efficient: create a new socket or use one already created?

I'm working on a Java client-server program. I use a socket to make the connection but I'm not sure about the efficiency. So, this is my question:
every time that I need a connection with a server, is it more efficient to create a new socket or to use the one created for the previous connection?
I think I need a method to verify if the client is already connected.
In terms of performance is more efficient re-using a previously created socket. But this don't need to be the best solution, it depends on each case.
The idiom case is having a ServerSocket in the server side that returns a Socket each time a new client connects to to it. If you require multiple clients to work against the server you could create a Thread to treat each client passing it the returned Socket.
Moreover, you don't need a method to verify you have a client already connected, ServerSocket returns a new Socket each time it happens.
Please, read more about this topic in Oracle tutorials.

Swing TCP Client ends connection to server but can then reconnect afterwards

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.

Reconnect to server when socket is closed

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.

Categories