繁体   English   中英

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

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

使用套接字解决此问题。 我写了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();
    }

在完成客户端之前,您正在关闭客户端连接。 在您的Server类中尝试以下操作:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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