Connection reset by peer: socket write error. What

2019-02-27 12:10发布

问题:

I am trying to create and maintain a TCP connection to a host from a standalone java application.

Local port and server port is same = 8999. After connection, I have to send a msg to the server: < STX >username=fred&password=abcd< ETX >.

The code for socket creation and message sending goes like:

Socket socket = new Socket("mshxml.abcd.com", 8999,   InetAddress.getLocalHost(), 8999);
OutputStream outStream = socket.getOutputStream();
while (socket.isConnected()) {
  try {
       int stx = 2, etx = 3;
       DataOutputStream dout = new DataOutputStream(outStream);
       dout.writeByte(stx);
       dout.writeBytes("username=fred&password=abcd");
       dout.writeByte(etx);
    } catch (Exception e) {
        e.printStackTrace();
}

But the connection does not persist. On debugging, I find the following error:

java.net.SocketException: Connection reset by peer: 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.voya.socketprog.CClient.createConnection(CClient.java:120)
        at com.voya.socketprog.CClient.createSocket(CClient.java:33)
        at com.voya.socketprog.CClient.main(CClient.java:138) Line 120 is: dout.writeBytes("username=fred&password=abcd");

Note: This same program runs successfully when connected to a dummy server (localhost) on my machine where I am able to receive and send messages.

Please help.

回答1:

while (socket.isConnected()) {

The problem is here.

  1. There is no reason for the while loop in the first place. It's a login message: it only needs to be sent once. The server almost certainly isn't expecting a second one from a logged-in connection, so it is closing.

  2. isConnected() is not a valid test for the connection still being present. The only valid test is the absence of an IOException such as the one you're getting, which means the peer has closed the connect. And when you get such an exception, all you can do is close the socket and stop trying. Retrying is pointless: the connection has gone.

Socket.isConnected() only tells you about the state of the Socket. Not of the connection. You connected this socket, so it's connected.

NB You should use the same streams for the life of the socket, not create a new one per message.



回答2:

@EJP @weston The issue has been resolved after much hit & trial. The working code is as follows:

Socket socket = new Socket("mshxml.abcd.com", 8999, InetAddress.getLocalHost(), 8999);
OutputStream outStream = socket.getOutputStream();

  try {
   String STX =  new Character((char) 2).toString();
   String ETX =  new Character((char) 3).toString();
   OutputStreamWriter osw = new OutputStreamWriter(outStream);
   BufferedWriter bw = new BufferedWriter(osw);

   bw.write( STX + "username=fred&password=abcd" + ETX ); 
   bw.flush();
} catch (Exception e) {
    e.printStackTrace();
}

But I have zero idea why is this code working and the original was not. Any suggestions would be much appreciated. And many thanks for bearing with my queries and duplicate posts. :)

@EJP regarding your thought about server closing the connection between receiving STX and next line, you are right. The server didnt close the connection right away; it was only during debugging (when the server got enough time to analyse the bytes) that I noticed it was doing so.