ERROR GServerHandler - java.io.IOException: Connection reset by peer
java.io.IOException: Connection reset by peer
at sun.nio.ch.FileDispatcher.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(Unknown Source)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source)
at sun.nio.ch.IOUtil.read(Unknown Source)
at sun.nio.ch.SocketChannelImpl.read(Unknown Source)
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:323)
at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:282)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:202)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
This log is from a game server implemented using netty. What can cause this exception ?
java.io.IOException: Connection reset by peer
The other side has abruptly aborted the connection in midst of a transaction. That can have many causes which are not controllable from the server side on. E.g. the enduser decided to shutdown the client or change the server abruptly while still interacting with your server, or the client program has crashed, or the enduser's internet connection went down, or the enduser's machine crashed, etc, etc.
To expand on BalusC's answer, any scenario where the sender continues to write after the peer has stopped reading and closed its socket will produce this exception, as will the peer closing while it still had unread data in its own socket receive buffer. In other words, an application protocol error. For example, if you write something to the peer that the peer doesn't understand, and then it closes its socket in protest, and you then continue to write, the peer's TCP stack will issue an RST, which results in this exception and message at the sender.
java.io.IOException in Netty means your game server tries to send data to a client, but that client has closed connection to your server.
And that exception is not the only one! There're several others. See BadClientSilencer in Xitrum. I had to add that to prevent those errors from messing my log file.
java.io.IOException: Connection reset by peer
In my case, the problem was with PUT requests (GET and POST were passing successfully).
Communication went through VPN tunnel and ssh connection. And there was a firewall with default restrictions on PUT requests... PUT requests haven't been passing throughout, to the server...
Problem was solved after exception was added to the firewall for my IP address.
For me useful code witch help me was http://rox-xmlrpc.sourceforge.net/niotut/src/NioServer.java
// The remote forcibly closed the connection, cancel
// the selection key and close the channel.
private void read(SelectionKey key) throws IOException {
SocketChannel socketChannel = (SocketChannel) key.channel();
// Clear out our read buffer so it's ready for new data
this.readBuffer.clear();
// Attempt to read off the channel
int numRead;
try {
numRead = socketChannel.read(this.readBuffer);
} catch (IOException e) {
// The remote forcibly closed the connection, cancel
// the selection key and close the channel.
key.cancel();
socketChannel.close();
return;
}
if (numRead == -1) {
// Remote entity shut the socket down cleanly. Do the
// same from our end and cancel the channel.
key.channel().close();
key.cancel();
return;
}
...
There are lot of factors , first see whether server returns the result, then check between server and client.
rectify them from server side first,then check the writing condition between server and client !
server side rectify the time outs between the datalayer and server
from client side rectify the time out and number of available connections !
It can also mean that the server is completely inaccessible - I was getting this when trying to hit a server that was offline
My client was configured to connect to localhost:3000, but no server was running on that port.
Related
I currently have a simple instant messaging program which is utilizing Java's Socket and ServerSocket classes. It is functioning as intended but when I attempt to close the connection it is not using the 4 way handshake TCP teardown to close the connection. Instead it is closing the connection abruptly with an RST packet.
The way in which I am closing the connection is sending a string from the client to the server which the server will recognize as the command to close the connection. I then use the ServerSocket.close() method on the server and the Socket.close() method on the client.
What is the correct way and/or order of events to properly close a TCP connection utilizing these classes?
Client side disconnect code:
//Disconnects from remote server
//Returns true on success, false on failure
public boolean disconnect(){
try{
this.clientOut.println("0x000000");
this.clientRemoteSocket.close();
this.isConnected = false;
return true;
}catch(Exception e){
return false;
}
}
Server side disconnect code:
//Check to see if the client wants to close the connection
//If yes, then close the connection and break out of the while loop
if(incoming.equals("0x000000")){
serverLocalSocket.close();
break;
}
EDIT:
The code works perfectly fine. I'm just trying to learn socket programming in Java and know that a proper TCP teardown process is to include a 4 way handshake. A FIN packet to the remote host, then an ACK packet from the remote host back. Then a FIN packet from the remote host, then an ACK packet to the remote host. When monitoring the traffic via Wireshark I am not getting that. Instead I am getting a FIN to the remote server, then a RST/ACK back from the server.
This image depicts a proper TCP 4 way teardown process.
So far everything I've found suggest that all one needs is a call to close() or to just let Java's Try-with-resources statement handle the clean up. I can't see Java implementing functionality which does not comply with the standard TCP specifications though. It is very possible I may be calling certain lines in an incorrect order or something of the sort, I'm just unaware of it.
If you are resetting your own connection on close, either:
You haven't read all the pending incoming data that was sent by the peer, or
You had already written to the connection which had previously already been closed by the peer.
In both cases, an application protocol error.
The great part about TCP is if you close your socket, your partner will automatically know and throw an error on reading.
So all you have to do in the client is:
clientRemoteSocket.close();
And with the server, just add an error case to your normal reading of data:
try {
// Read from the socket:
incoming = socketInputStream.read();
// Handle the data here
} catch (IOException e) {
// Client has disconnected
}
There might be a more specfic exception you can catch, I'm not sure, it's been a while. But that should work. Good luck!
This question already has answers here:
Detecting TCP Client Disconnect
(9 answers)
Does a TCP socket connection have a "keep alive"?
(8 answers)
Closed 7 years ago.
I have written java client server socket connection code. In that the server accepts the client connection, then the server sends the data using PrintStream , and client reads the data in readline(). After this, the client will wait for the server in readline. If there is a network disconnection, the client keeps waiting in the readline and never exits from readline. Is there is a way to detect the disconnection from client side itself? Or whether I have to write new heartbeat thread to check network disconnection?
Turn on socket option SO_KEEPALIVE on the socket. This will enable a heartbeat feature built into the TCP protocol.
Here's a simple way to turn this on.
Socket socket = ...; // Your socket on the client side
socket.setKeepAlive(true);
If the other side of the connection stops responding to the heartbeats, you will get an IOException on your call to read from the socket.
However, the timeout for this is 2 hours. This may be too long for your needs (you didn't specify)
Disconnection from the client side:
clientSocket.isConnected(): this is wrong, this will not return true and will keep returning false until the server has also disconnected
You can try to send data through an output stream and you will get an exception, specifically IOException (Broken Pipe)
You can also use socket.keepAlive(true) this will use the heartbeat feature built into the socket and you will get an exception because of it.
Cheers.
I've got a very simple multithreaded server that just prints back the client's input. The problem I'm having is that the client is crashing out after more than one use of outToServer.writeBytes().
My source code for the client is here:
public class Client {
public void run() throws Exception{
String sentence;
Socket clientSocket = new Socket("localhost", 25565);
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
while (true){
sentence = inFromUser.readLine();
if(!sentence.equalsIgnoreCase("exit")){
outToServer.writeBytes(sentence + '\n');
} else {
break;
}
}
clientSocket.close();
}
}
I've done some research on the error and it might be my college network killing the connection, but it doesn't make much sense given that it allows the first connection.
Also, here's the error:
java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at java.io.DataOutputStream.writeBytes(Unknown Source)
at com.cs.Client.run(Client.java:21)
at com.cs.Main.main(Main.java:14)
At line 21 in Client.java is the line with writeBytes in it
Opening a connection is not like opening a door. A connection is a virtual concept and not a guaranteed path.
So when you open a connection, basically you have reconfigured some operating system managed area of memory to know that when you write data into a particular memory location, it needs to copy that data on the wire.
This means that opening a connection is not always a shared event (as in the remote machine might not fully guarantee a path to the program, or even might not be aware that a path to the remote program was requested).
So, in network programming, despite APIs that are worded to imply otherwise, you don't have a functional connection until you get the first response from the remote machine.
I'd see if you can fire up wireshark and see if you can capture the data prior to send, and I'd check any connection parameters, and attempt to verify connection reachability independently of the program.
The above procedure will help you quickly identify which network componet is at fault from the client's point of view; however, 90% of the time, it is something really trivial, like a software firewall blocking the desired port.
Also, you can use telnet to provide similar functionality, but connecting to a non-standard port.
telnet hostname 25565
Good luck, and your code seems pretty reasonable, I'd spend a little time making sure that you aren't focusing on the code when the environment might be at fault.
public static void main(String args[]){
byte[] message = ...
Socket socket = ...
DataOutputStream dOut = new DataOutputStream(socket.getOutputStream());
dOut.write(message); //#1
dOut.close();
socket.close();
}
Let's assume that the line #1 will put the data into buffer waiting to flush to remote machine. After that the stream and socket are closed.
We assume that, in the sending process, there is some unknown problem happens in network, and our operating system will resend the packet that was in the buffer until the TCP re-tranmission timeout.
I am wondering that how I can catch this exception in Java program? Because the code above already send out data to buffer and probably closed the stream and socket (and probably exit the Java main body), left all the other job (TCP-related, re-tranmission) to operating system.
My question is, will the TCP re-tranmission (we assume packet lost) continue even Java program exit? What is the best method to catch the re-tranmission timeout error?
TCP will continue to try to cleanly shutdown the connection even after the program exits. It is generally recommended that the application perform the shutdown itself. Basically, you perform the following sequence of steps:
Shutdown the TCP connection in the send direction triggering the normal close sequence. If the protocol prohibits the other side from sending any data, you can shutdown the connection in the receive direction as well, however, if you do this and the other side sends any data, it may cause the other side to detect an abnormal shutdown as the data it sent will be lost.
Continue to read from the connection until you detect a clean or abnormal shutdown from the other end. If all goes well, you will detect a clean shutdown as soon as you finish receiving any data the other side has sent.
Close the handle or delete the object/reference to the connection. The actual TCP connection is already shut down.
Essentially I have a server class and a client class, the client creates a socket and sends whatever you type into the server, which gets written to the output streams of a vector of sockets from all the existing clients. It works well except when you close a chat client, after which the next message sent gives the following exception:
java.net.SocketException: Software caused connection abort: socket write error
I think what's happening is that the socket closed by the client is either not closing the socket in the server's vector of sockets, or that even when it's closed, it remains in the vector and then tries to write to a closed socket. Does this sound like what might be happening? I don't understand exactly what the socket.close() method does regarding the socket it's connected to.
You close the socket on the client side, but on the server side it is not closed and this is why you get this exception.
In a graceful close you should send a CLOSE message from your client which will close the socket on the server side.
If a socket on the client was closed then you must handle your exception on the server side e.g. by removing it from your vector of sockets.
If the client closes his socket you will read EOS at the server (read() returns -1, readLine() returns null,readXXX() throws EOFException for any other X), or get an IOException: connection reset by peer when writing, probably not on the first write. If either of these things happens you must close the socket in the server and forget about that client in all ways.
I don't think it's like both sides of connection are holding together by hands, and if you split them they always will feel it. Check if socket is closed before sending and catch exceptions to solve this problem.