How can I get notified of client disconnects? - java

ServerSocket serverSocket = new ServerSocket(portNumber)
Socket socket = serverSocket.accept();
try (
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
) {
while (in.readLine() != null) {
//do something
}
System.out.println("reach me if you can");
socket.close();
}
Writing my Server/Client software, I tried to implement functionality to show number of current connections. But I realized that my server never gets the message when a client abruptly terminates; it just keeps waiting at in.readLine(). How should I ensure that a Thread created to handle a specific connection is not left running while the connection is dead?

It is a general TCP problem that the machine on one end of a connection can go away without any notification to the machine on the other end. Machines are not supposed to do that, but it isn't always under their control. The usual way for one end to avoid waiting forever for data in such a case, and / or to avoid being loaded down with dead connections, is to employ a timeout.
The general problem is bigger than you described, but you should be able to solve the particular part you asked about by invoking setSoTimeout() on the socket some time before you try to read from it. The socket will then throw an exception if your read attempt blocks for longer than the time you specify. This setting persists for the lifetime of the socket (or until you set a different value), so you can apply it immediately after accepting the connection if you wish.
Be aware, however, that a sufficiently long period of simple client inactivity can also cause a timeout.

Related

Stopping blocking sockets in java

I have a java socket calling a server. However, I do not know at which address I can reach the server, so I put several sockets in several threads and they try to reach the server each on one address. My probem is that I do not want to wait for the timeout but have no idea how to stop the sockets and their threads properly.
Code:
socket = new Socket();
socket.connect(endpoint, timeout); // **Blocking method**
OutputStream out = socket.getOutputStream();
//Write Data here
How can I interrupt the operation? I consider Thread.stop() a bad style and it also does not work properly. .NET Tcp Endpoints have a non-blocking pending method that allows uinsg boolean flags but I could not find something similiar
I do not know at which address I can reach the server, so I put
several sockets in several threads and they try to reach the server
each on one address.
BAD. BAD Decision. Perform some logical step to determine the server's address. Or, perform something that helps you know about the server's IP-Address.
Do this way, only if it is the last hope.
My problem is that I do not want to wait for the
timeout but have no idea how to stop the sockets and their threads
properly.
You don't have any other option that timeout. Socket.connect() is blocking. You can't do anything than waiting.
You've to wait for timeout because that is the logical way to close the socket object created. You can't just do close directly, until a timeout. Reduce the timeout to the limit when your result should come(connection should be accepted).
How can I interrupt the operation? I consider Thread.stop() a bad
style and it also does not work properly.
Yes, you should not perform Thread.stop() or Thread.interrupt(). These are bad programming styles.
If the timeout expires, make the close() operation on socket.
You should set a socket timeout for the client-socket. It is the best-practice to set a timeout for sockets. The timeout should be around 10 seconds to more depending on the needs.
You can set the timeout in your current code by calling
socket.setSoTimeout(timeout); for reading timeout, OR
for connect timeout, connect(endpoint,timeout) as you've done in your code.
If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout.
You're probably not using a try-catch-finally in your code. That'd be a better design here.
As you're doing a connect timeout, so your code can be amended to exit the blocking method like as shown below :
try{
socket = new Socket();
socket.connect(endpoint,timeout); // **Blocking method**
OutputStream out = socket.getOutputStream();
//Write Data here
}
catch(Exception e){
e.printStackTrace();
}
finally{
socket.close();
}

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 :)

Android-App consume to much energy. Sockets maybe the reason

In my app I use a datagramSocket, one serversocket and several sockets. When my app runs on my android-device, the phone get hot on one area and it needs lots of energy.
I think the reason for the problem are my Sockets. But Im not sure which opperation are so energy-consuming:
Does it cost much energy to create new Sockets:
Socket so = new Socket();
ss = new ServerSocket( port );
mSocket = new MulticastSocket( port );
Is it importand to close the serversocket and other sockets if I don't need it anymore.
Does connecting cost energy?
so.connect( new InetSocketAddress(ip, port ), 1000);
And after connecting does the connection need much energy?(Is it better to disconnect when i don't send datas for a long time)
Does a high amount of Sockets need much energy?
I also have several threads:
Beside my main-thread and three binderthreads, I have three more:
1st Thread: listen for incoming message on my datagram-socket:
DatagramPacket packet = new DatagramPacket(buffer, buffer. length);
mSocket .receive(packet);
2nd Thread: listen for incoming messages on several sockets:
try {
if (objectInputStreamList .size() != 0){
if (counter >= objectInputStreamList .size()){
counter = 0;
}
ObjectInputStream ois = objectInputStreamList .get(counter);
Object o = ois.readObject();
if (o instanceof Message){
receive((Message) o);
System.out .println("Message received in Server");
}
}
} catch (SocketTimeoutException soTOE){
counter++;
}
3rd Thread: send Datas via an http-request via internet to a server.
Does one of the threads need much energy?
The app needs also much energy even if wifi is turned off or wifi is turned on but not connected to wlan.
And so there are no connections.
Which of this opperations are energyconsuming? And what can I do to reduce the energy?
Thank you for your answers.
Given that it runs hot even when it's not supposed to do anything, I suspect one of your threads are running freely instead of properly blocking. Can't tell you more without the complete source code, but some good old printf debugging might come in handy. Simply put different logging statements in each of your while loops and run the program. If a statement fills your log at an alarming rate, then there you have it.
Yes you should always close a socket that you no longer need. For example, if you don't close your server sockets then their ports will remain occupied. Eventually the system will run out of ports. (I could come up with many other reasons, including resource usage and elegance. Tidying things up might even make the problem obvious.)
FYI having many sockets open does not cost energy in and of itself. Network activity costs a little energy (pay attention to idle timers!), but it shouldn't make one part of your device really hot.

Why should I use NIO for TCP multiplayer gaming instead of simple sockets (IO) - or: where is the block?

I'm trying to create a simple multiplayer game for Android devices. I have been thinking about the netcode and read now a lot of pages about Sockets. The Android application will only be a client and connect only to one server.
Almost everywhere (here too) you get the recommendation to use NIO or a framework which uses NIO, because of the "blocking".
I'm trying to understand what the problem of a simple socket implementation is, so I created a simple test to try it out:
My main application:
[...]
Socket clientSocket = new Socket( "127.0.0.1", 2593 );
new Thread(new PacketReader(clientSocket)).start();
PrintStream os = new PrintStream( clientSocket.getOutputStream() );
os.println( "kakapipipopo" );
[...]
The PacketReader Thread:
class PacketReader implements Runnable
{
Socket m_Socket;
BufferedReader m_Reader;
PacketReader(Socket socket)
{
m_Reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
public void run()
{
char[] buffer = new char[200];
int count = 0;
while(true)
{
count = m_Reader.read(buffer, 0, 200);
String message = new String(buffer, 0, count);
Gdx.app.log("keks", nachricht);
}
}
}
I couldn't experience the blocking problems I should get. I thought the read() function will block my application and I couldn't do anything - but everything worked just fine.
I have been thinking: What if I just create a input and output buffer in my application and create two threads which will write and read to the socket from my two buffers? Would this work?
If yes - why does everyone recommend NIO? Somewhere in the normal IO way there must a block happen, but I can't find it.
Are there maybe any other benifits of using NIO for Android multiplayer gaming? I thought that NIO seems to be more complex, therefore maybe less suited for a mobile device, but maybe the simple socket way is worse for a mobile device.
I would be very happy if someone could tell me where the problem happens. I'm not scared of NIO, but at least I would like to find out why I'm using it :D
Greetings
-Thomas
The blocking is, the read() will block current thread until it can read data from socket's input stream. Thus, you need a thread dedicate on that single TCP connection.
What if you have more than 10k client devices connected with your server? You need at least 10k threads to handle all client devices (assume each device maintain a single TCP connection) no matter they are active or not. You have too much overhead on context switch and other multi-threads overhead even only 100 of them are active.
The NIO use a selector model to handle those clients, means you don't need a dedicate thread for each TCP connection to receive data. You just need to select all active connections (which has data already received) and to process those active connections. You can control how many threads should be maintained in server side.
EDIT
This answer is kind of not exactly answering about what OP asked. For client side its fine because the client is going to connect to just one server. Although my answer gives some generic idea about Blocking and Non Blocking IO.
I know this answer is coming 3 years later but this is something which might help someone in future.
In a Blocking Socket model, if data is not available for reading or if the server is not ready for writing then the network thread will wait on a request to read from or write to a socket until it either gets or sends the data or
times out. In other words, the program may halt at that point for quite some time if it can't proceed. To cancel this out we can create a thread per connection which can handle out requests from each client concurrently. If this approach is chosen, the scalability of the application can suffer because in a scenario where thousands of clients are connected, having thousands of threads can eat up all the memory of the system as threads are expensive to create and can affect the performance of the application.
In a Non-Blocking Socket model, the request to read or write on a socket returns immediately whether or not it was successful, in other words, asynchronously. This keeps the network thread busy. It is then our task to decide whether to try again or consider the read/write operation complete. Having this creates an event driven approach towards communication where we can create threads when needed and which leads to a more scalable system.
Diagram below explains the difference between Blocking and Non-Blocking socket model.

Best way to block on a socket for data

What is the efficient way of blocking on the socket for data after opening it.The method i used is to call read on input stream (this is a blocking call that waits till some data written to this socket).
//Socket creation
SocketForCommunication = new Socket();
InetSocketAddress sAddr = new InetSocketAddress("hostName", 8800);
SocketForCommunication.connect(sAddr,10000);
is = new DataInputStream(SocketForCommunication.getInputStream());
os = new DataOutputStream(SocketForCommunication.getOutputStream());
//Waiting on socket using read method for data
while(true)
{
int data = is.read();
if(data == HEADER_START)
{
processPackage(is);
}
}
Here problem is read can timeout.Is there a way to register a callback that gets called when data available to read on socket.?
The socket will timeout by default, but you can change this if you really want to. See the Socket.setSoTimeout() call (a timeout of zero means "indefinite").
N.B. Even if you specify a zero timeout, your O/S may or may not actually let you keep a socket open indefinitely. For example, idle sockets may get closed after a certain amount of time. In environments, e.g. shared web hosting environments, it's not uncommon for a housekeeping routine to also run (say) once a day and shut down idle sockets.
And of course, stuff happens on networks. Either way, you shouldn't rely on the socket staying open indefinitely...
You want to use the java.nio (non blocking IO) system. While its not callback driven, it allows you much more flexibility in handling IO.
http://rox-xmlrpc.sourceforge.net/niotut/index.html

Categories