【问题标题】:SocketException recv failed, but why?SocketException recv 失败,但是为什么?
【发布时间】:2017-03-05 00:26:26
【问题描述】:

我有一个客户端和一个服务器。客户端只需向服务器发送 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)

调试器告诉我在读的时候socket没有关闭,还有什么会导致这个异常?

我认为由于线程问题,我遇到了问题,是否有任何问题突出为“做错了”?

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)
    { /* ... */ }

【问题讨论】:

  • 尝试在写入后在客户端的影响力上调用flush()
  • 不,这并没有解决问题。
  • 我也不会使用 in.ready() 。毫无意义。如果它立即返回 null 怎么办?什么都没有发生...摆脱它...只是阅读

标签: java sockets tcp


【解决方案1】:

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

【讨论】:

  • 手动将换行符附加到 sc.nextLine() 并不能解决问题 (byte[] cl = (sc.nextLine()+'\n').getBytes("UTF-8");),我是否正确理解了您的答案?
  • 我还尝试将clout 更改为PrintWriter 并使用clout.println(sc.nextLine()),但也没有用。
猜你喜欢
  • 2012-05-29
  • 2015-05-31
  • 2017-02-27
  • 2010-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-28
相关资源
最近更新 更多