SocketException recv失败了,但为什么呢?

时间:2016-10-22 23:04:29

标签: java sockets tcp

我有一个客户端和一个服务器。客户端只需向服务器发送1行输入,然后打印响应。

我得到了

SocketException (Software caused connection abort: recv failed) 
    [...]
    at java.io.InputStreamReader.read(InputStreamReader.java:168)
    at hw3.Client.readLine(Client.java:37)
    at hw3.Client.main(Client.java:28)

调试器告诉我在读取时套接字没有关闭,还有什么可能导致这个异常?

我认为由于线程问题我遇到了问题,有什么事情突然出现“做错了”?

public class Client
{
    public static final int PORT = ReversingEchoServerDispatcher.PORT;
    private static final String host = "localhost";
    private static Socket sock;

    public static void main(String[] args)
      throws IOException
    {
        try(Socket sock = new Socket(host, PORT);
            InputStreamReader clin = new InputStreamReader(sock.getInputStream());
            OutputStream clout = sock.getOutputStream();
            Scanner sc = new Scanner(System.in))
        {
            Client.sock = sock;

            byte[] cl = sc.nextLine().getBytes("UTF-8");
            clout.write(cl);
            System.out.println(readLine(clin));
        }
    }

    private static String readLine(InputStreamReader in)
      throws IOException
    {
        StringBuilder sb = new StringBuilder();
        for(int i = in.read(); i != -1; i = in.read())
        {
            char c = (char) i;
            if(c != '\n') sb.append(c);
            else break;
        }
        return sb.toString();
    }
}

public class ServerDispatcher
{
    public static final int PORT = 8034;
    public static void main(String[] args)
    {
        try (ServerSocket serversock = new ServerSocket(PORT))
        {
            while(true)
            {
                Socket socket = serversock.accept();
                ServerLogic sv = new ServerLogic(socket);
                new Thread(() -> {
                    try {
                        sv.run();
                    } catch (IOException ex) {
                        ex.printStackTrace(System.err);
                    }
                }).start();
            }
        }
        catch(IOException e)
        {
            e.printStackTrace(System.err);
        }
    }
}

对于记录,ServerLogic类看起来如下所示。我的退出代码是1,而不是-999,所以它不是socket.close()失败

class ServerLogic
{
    Socket socket;

    public
    ServerLogic(Socket s)
    {
        this.socket = s;
    }

    public void run()
      throws IOException
    {
        try(InputStreamReader in = new InputStreamReader(socket.getInputStream());
            OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream()))
        {
            StringBuilder sb = new StringBuilder();
            while(in.ready()) {
                char c = (char) in.read();
                if(c == '\n') {
                    String str = process(sb);
                    if(str != null) out.write(str);
                    else return;
                } else {
                    sb.append(in.read());
                }
            }
        } finally {
            try {
                socket.close();
            } catch(IOException ex) {
                ex.printStackTrace(System.err);
                System.exit(-999);
            }
        }
    }

    private static String process(StringBuilder sb)
    { /* ... */ }

1 个答案:

答案 0 :(得分:0)

服务器期望换行符\n终止输入,但您永远不会从客户端发送一个。 sc.nextLine()返回输入行,但不包括终止换行符。 while(in.ready())循环最终结束,服务器关闭套接字而不发送响应。