java.net.SocketException:软件导致连接中止:重新提交请求时套接字写入错误

时间:2018-09-20 13:55:14

标签: java sockets server

使用套接字解决此问题。我写了Http和TCP服务器的实现。 HTTP完全可以正常工作,因此我可以将请求一一发送到服务器。关于TCP服务器,不能说什么,第一个请求离开并被正确处理,但是当您尝试发送以下请求时,将引发此异常:

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)

此后,客户端关闭,服务器端继续工作。HTTP和TCP是从同一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();
            }
        }
    }

启动服务器的类:

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客户端:

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);
                }
            }
        }
    }

为什么当我重新向TCP服务器提交请求时,我得到上面指示的异常?为什么在向HTTP服务器发送第二个请求时没有抛出该异常?

@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();
    }

2 个答案:

答案 0 :(得分:1)

您要在完成客户端之前关闭客户端连接。在您的服务器类中尝试以下操作:

@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();
    }
  }
}

答案 1 :(得分:0)

您的服务器在发送响应后似乎关闭了套接字。此后,如果不打开新连接,客户端将无法发送其他请求。通常,服务器允许客户端控制连接的命运,以便客户端可以发送多个请求。您的客户端可以发送“关闭”请求,以向服务器表明客户端打算关闭套接字,并且不希望响应。