【问题标题】:How to exit/disconnect from telnet properly?如何正确退出/断开 telnet?
【发布时间】:2014-09-10 04:29:17
【问题描述】:

我正在远程登录到服务器,如果我没有正确断开连接,它将阻塞端口。我已经在使用 socket.close();所以我不确定完全断开与服务器的连接我做错了什么

//java socket client example
import java.io.*;
import java.net.*;

public class socket_client {
  public static void main(String[] args) throws IOException {
    Socket s = new Socket();
    String host = "1.1.1.1";
    PrintWriter s_out = null;
    BufferedReader s_in = null;

    try {
        s.connect(new InetSocketAddress(host, 12656));
        System.out.println("Connected");

        // writer for socket
        s_out = new PrintWriter(s.getOutputStream(), true);
        // reader for socket
        s_in = new BufferedReader(new InputStreamReader(s.getInputStream()));
    }

    // Host not found
    catch (UnknownHostException e) {
        System.err.println("Don't know about host : " + host);
        System.exit(1);
    }

    // Send message to server
    String message = "this is the msg";
    s_out.println(message);

    System.out.println("Message send");

    // Get response from server
    String response;
    while ((response = s_in.readLine()) != null) {
        System.out.println(response);
    }
    // close the socket

    s.close();
    // close the i/o streams
    s_out.close();
    s_in.close();

}

}

【问题讨论】:

    标签: java telnet


    【解决方案1】:

    由于服务器端未处理意外的套接字关闭,因此套接字被阻塞。您有两种选择 - 或者更确切地说,如果您想彻底解决这个问题,则需要两个步骤。

    1. 处理连接的另一端意外关闭 异常处理程序,并在需要时关闭套接字。
    2. 让客户端在需要时向服务器发送消息 关闭连接,允许服务器关闭套接字,并且 然后将该关闭的套接字作为成功操作处理。

    这是一个优雅地处理意外终止的server socket code from O'Reilly 示例:

    try {
      ServerSocket server = new ServerSocket(5776);
      while (true) {
        Socket connection = server.accept(  );
        try {
          OutputStreamWriter out 
           = new OutputStreamWriter(connection.getOutputStream(  ));
          out.write("You've connected to this server. Bye-bye now.\r\n");        
          connection.close(  );
       }
       catch (IOException e) {
         // This tends to be a transitory error for this one connection;
         // e.g. the client broke the connection early. Consequently,
         // we don't want to break the loop or print an error message.
         // However, you might choose to log this exception in an error log.
       }
       finally {
         // Most servers will want to guarantee that sockets are closed
         // when complete. 
         try {
           if (connection != null) connection.close(  );
         }
         catch (IOException e) {}
       }
    }
    catch (IOException e) {
      System.err.println(e);
    }
    

    【讨论】:

    • 代码实际上是通常奇怪的 O'Reilly 代码。其他任何人都会在单独的线程中处理连接,而我认识的任何人都不会忽略 IOException。
    • 我强烈怀疑它是自制服务器和客户端,因此我链接了服务器端脚本。它至少指向了优雅地处理它的大方向。
    • 同意,肯定是服务器坏了。但是问题之一肯定是它像这段代码一样是单线程的:否则它不能“阻塞端口”。否则整个问题都是虚构的。
    【解决方案2】:

    Telnet 中没有断开子协议。您所要做的就是关闭套接字。

    我从未见过或听说过 Telnet 服务器“如果我没有正确断开连接会阻止端口”。我有一个生产 Telnet 客户端,它只做这个,并且已经正常工作了五六年。任何不能正确处理意外断开连接的服务器都存在非常严重的问题。

    问题出在其他地方,可能在(未指定的)服务器本身。要按照您的描述行事,它必须完全忽略流结束条件,并且也忽略 IOExceptions(或者将它们视为对整个过程完全致命)。它也必须是单线程的。我发现很难相信存在这样的服务器,或者确实存在这个问题。

    注意,您只需要关闭“s_out”,即您包裹在套接字输出流周围的最外层流/写入器。如果您必须关闭输入流和套接字,请在关闭输出流/写入器之后执行此操作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-03
      • 2012-07-18
      • 1970-01-01
      • 1970-01-01
      • 2022-05-24
      • 2020-04-05
      • 2023-03-02
      • 2015-11-24
      相关资源
      最近更新 更多