【问题标题】:Java OutputStream/TelnetClient can't write string longer than 1955 charactersJava OutputStream/TelnetClient 不能写入超过 1955 个字符的字符串
【发布时间】:2015-04-30 09:47:52
【问题描述】:

我必须创建一个客户端,它从套接字接收请求并将它们发送到我们的 telnet 旧服务器并返回服务器响应。在我们最近意识到我发送的一些命令在 1955 个字符处被截断之前,它一直运行良好。一切设置的方式是我向服务器发送 1 行命令,然后它发回 1 行响应。我想不出一种通过 TelnetClient 通过 DataOutputStream 发送更长命令的方法。我做错了还是这只是这些对象之一的限制?

public void connect() {
    try {
        tc = new TelnetClient();
        TerminalTypeOptionHandler ttopt = new TerminalTypeOptionHandler("VT100", false, false, true, false);
        EchoOptionHandler echoopt = new EchoOptionHandler(true, false, true, false);
        SuppressGAOptionHandler gaopt = new SuppressGAOptionHandler(true, true, true, true);
        try {
            tc.addOptionHandler(ttopt);
            tc.addOptionHandler(echoopt);
            tc.addOptionHandler(gaopt);
        } catch (InvalidTelnetOptionException e) {
            ServerConsole.log(e.getMessage());
        }
        tc.connect("192.168.1.8", 2010);
        in = new DataInputStream(tc.getInputStream());
        out = new DataOutputStream(tc.getOutputStream());
        login();
    } catch (IOException ex) {
        ServerConsole.log(ex.getMessage());
    }
}

//This is a watered down version of my write method just to show the basic idea of whats happening
public String write(String command) {
    String finalCommand = command+"\n";
    byte[] comm = finalCommand.getBytes();
    out.write(comm);
    out.flush();
    response = in.readLine();
    response = in.readLine();
    return response;
}

【问题讨论】:

  • 你试过类似out = new DataOutputStream(new BufferedOutputStream(tc.getOutputStream(), BIG_NUMBER_HERE));吗?
  • 刚试过,我的命令在 1955 个字符处仍然被截断
  • 那么这可能是TelnetClient 中的缓冲区的问题。该类扩展了SocketClient,因此您可以使用tc.setReceiveBufferSize(BIG_NUMBER_HERE);tc.setSendBufferSize(BIG_NUMBER_HERE);
  • 我认为这不再是客户端的问题了。有关详细信息,请参阅我的答案。这不是一个真正的解决方案,但我希望能够发布我用来测试的客户端和服务器代码。

标签: java telnet apache-commons-net dataoutputstream


【解决方案1】:

我不知道这些对象,但你为什么不在消息的开头放一个字符,它表示这是否是消息的结尾。因为发送一个巨大的字符串看起来不太安全。

示例:字符“E”表示END,字符“N”表示NotEnded。

因此您的客户端可以继续接收消息并将它们连接成一个大字符串,而它没有收到带有字符“E”的消息。

示例: 接收……“NTheWorld……” 创建一个字符串“strMessage”; 接收...“NBurnYesterday...” 将接收到的消息与 strMessage 连接; 接收...“NTodayApple...” 将接收到的消息与 strMessage 连接; 接收...“ETheEnd” 字符串完成,我执行下一个操作。

(抱歉拼写错误)

【讨论】:

    【解决方案2】:

    经过一番修补,我认为这根本不是客户端问题。我拿了你的客户端代码并基于它编写了一个测试客户端。然后我写了一个(非常)基本的示例服务器,它打印出传入的消息并返回一个 ACK​​。

    即使将请求大小推到 100k 也不会导致来自客户端的消息被截断。您可能需要仔细查看您正在联系的服务器如何处理传入数据。

    客户

    public class TelnetClientTest {
        public static String LOCALHOST = "127.0.0.1";
        public static int PORT = 5003;
    
        public static void main(String[] args) throws Exception {
            TelnetClient tc = new TelnetClient();
            TerminalTypeOptionHandler ttopt = new TerminalTypeOptionHandler("VT100", false, false, true, false);
            EchoOptionHandler echoopt = new EchoOptionHandler(true, false, true, false);
            SuppressGAOptionHandler gaopt = new SuppressGAOptionHandler(true, true, true, true);
            try {
                tc.addOptionHandler(ttopt);
                tc.addOptionHandler(echoopt);
                tc.addOptionHandler(gaopt);
            } catch (InvalidTelnetOptionException e) {
                e.printStackTrace();
            }
            tc.connect(LOCALHOST, PORT);
            DataInputStream in = new DataInputStream(tc.getInputStream());
            DataOutputStream out = new DataOutputStream(tc.getOutputStream());
    
            StringBuilder sb = new StringBuilder();
            for (int i=0; i<1000; i++) {
                sb.append("0123456789");
            }
            sb.append("\n");
            out.write(sb.toString().getBytes());
            out.flush();
            System.out.println(in.readLine());
            tc.disconnect();
        }
    }
    

    服务器

    public class ServerSocketExample {
        private static ServerSocket server;
        private static int PORT = 5003;
    
        public static void main(String[] args) throws Exception {
            server = new ServerSocket(PORT);
            while (true) {
                System.out.println("Waiting for clients...");
                Socket s = server.accept();
                System.out.println("Client connected: " + s.getLocalAddress().getHostName());
    
                BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
                String request = reader.readLine();
                System.out.println("Client says ("+request.length()+"): " + request);
    
                System.out.println("Sending ACK response\n");
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
                writer.write("ACK\n");
                writer.flush();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-10-19
      • 2011-05-03
      • 2013-01-10
      • 1970-01-01
      • 2013-03-26
      • 2013-11-03
      • 1970-01-01
      • 2014-02-16
      • 2013-01-28
      相关资源
      最近更新 更多