0

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

2 Answers 2

1

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();
    }
  }
}
Sign up to request clarification or add additional context in comments.

4 Comments

I tried so, but then I'm in a loopless cycle. Therefore, I did so.So I added a test to the final block, where I check! IsConnectio; if the condition passes then close the socket. But the error continues
You want to be in a loop, until your client closes the connection. Can you post your getRequestand setResponse methods?
Yes, I applied to the post
When you do output.write(result); in your setResponse method, does result end with a '\n'? Because your client is reading a line, so it won't stop buffering until it detects a newline.
0

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.

2 Comments

Okay, but why then does the HTTP server work correctly and can I resend requests? And I close the socket only in one place, when I removed it, nothing has changed not counting auto-closing try with resources) But I do not close the server socket. I do not understand where I could be wrong :(
I'm looking at your Server class in the finally clause. I can't see the HTTP server, but I suspect it is not doing that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.