简体   繁体   中英

java.net.SocketException: Software caused connection abort: socket write error when resubmitting the request

working with sockets on this problem. I wrote the implementation of Http and TCP servers. HTTP works completely correctly, so I can send requests to the server one by one. What can not be said about the TCP server, the first request leaves and is handled correctly, but when you try to send the following request, throws this exception:

java.net.SocketException: Software caused connection abort: socket write error
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
    at java.net.SocketOutputStream.write(SocketOutputStream.java:134)
    at java.io.DataOutputStream.writeBytes(DataOutputStream.java:276)
    at Main.main(Main.java:24)

After that, the client side is closed, and the server side continues to work.HTTP and TCP are implemented from the same Server class, which starts the server.

MyServer:

public abstract class Server implements Runnable {

    private final Socket clientSocket;

    public Server(Socket clientSocket) {
        this.clientSocket = clientSocket;
    }

    @Override
    public void run() {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
             BufferedWriter output = new BufferedWriter(new PrintWriter(clientSocket.getOutputStream()))) {
            String req = getRequest(reader);
            setResponse(output, req);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

Class that starts the server:

public class RunServer extends Thread {
    private final int port;
    private ExecutorService executorService;
    private String serverType;
    private ServerFactoryContainer serverFactoryContainer;

    public RunServer(String serverType, int port) {
        this.port = port;
        this.executorService = Executors.newFixedThreadPool(4);
        this.serverType = serverType;
        this.serverFactoryContainer = new ServerFactoryContainer();
    }

    @Override
    public void run() {
            try {
                ServerSocket serverSocket = new ServerSocket(port);
                while (!isInterrupted()) {
                    Socket clientSocket;
                    try {
                        clientSocket = serverSocket.accept();
                        executorService.execute(serverFactoryContainer.getServerFactory(serverType).createServer(clientSocket));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

TCP client-side:

public class Main {
    public static void main(String[] args) throws IOException {
        String req;
        String resp;

        try (Socket clientSocket = new Socket(InetAddress.getLocalHost(), Constants.ServerConstant.TCP_PORT);
             BufferedReader inFromClient = new BufferedReader(new InputStreamReader(System.in));
             DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
             BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {
            while (true) {
                System.out.println("Write command [get count] or [get item]");
                req = inFromClient.readLine().toLowerCase();
                outToServer.writeBytes(req + "\n");  // I get an exception here when I send a request to the server

                resp = inFromServer.readLine();
                if (!resp.isEmpty()) {
                    System.out.println(resp);
                }
                if (req.equals("exit")) {
                    System.exit(1);
                }
            }
        }
    }

Why do I get the exception that I indicated above when I resubmit the request to the TCP server and why is this exception not thrown when sending a second request to the HTTP server?

@Override
    protected String getRequest(BufferedReader input) throws IOException {
        return input.readLine();
    }

    @Override
    protected void setResponse(BufferedWriter output, String request) throws IOException {
        String result = serverCommandController.execute(RequestParser.tcpParserCommand(request));
        output.write(result);
        output.flush();
    }

You are closing the client connection before the client is done. Try this in your Server class:

@Override
public void run()
{
  try (BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); BufferedWriter output = new BufferedWriter(new PrintWriter(clientSocket.getOutputStream())))
  {
    while (clientSocket.isConnected())
    {
      String req = getRequest(reader);
      setResponse(output, req);
    }
  }
  catch (IOException e)
  {
    e.printStackTrace();
  }
  finally
  {
    try
    {
      clientSocket.close();
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
  }
}

Your server appears to close the socket after sending a response. After that, the client will not be able to send further requests without opening a new connection. Typically, the server allows the client to control the fate of the connection, so that the client can send multiple requests. Your client could send a "close" request to indicate to the server that the client intends to close the socket and does not expect a response.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM