You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Telnet接收的含乱码字符串中提取数字?附Socket服务器代码

解决Telnet输入乱码与数字提取失败问题

看起来你遇到的核心问题有两个:一是Telnet客户端(Putty)收到/发送的字符串包含乱码,二是无法正确提取输入中的数字。让我们一步步解决这些问题:

1. 字符编码一致性问题(乱码根源)

你的代码中输入输出流明确指定了UTF-8,但创建STZ_DAVOR和STZ_DANACH这两个控制字符字符串时,使用了系统默认编码(没有指定编码参数),这会导致这些字节被错误解码,发送到客户端后显示为乱码,甚至客户端回显时带回这些乱码字符。

修复方法:创建字符串时指定UTF-8编码,和输入输出流保持一致:

private static final String STZ_DAVOR = new String(
    new byte[]{0x0b, 0x1b, '[', '1', 'A', 0x1b, '7', 0x1b, '[', '1', 'L', '\r'},
    Charset.forName("utf-8")
);
private static final String STZ_DANACH = new String(
    new byte[]{0x1b, '8', 0x1b, '[', '1', 'B'},
    Charset.forName("utf-8")
);

2. 输入读取逻辑的致命bug

在桌号验证的代码中,你连续调用了三次in.readLine():

table = in.readLine();
// ...
else if (in.readLine().equals("") || in.readLine().contains(" ")) {

这会导致你跳过用户的输入行!第一次读取的table是用户输入的内容,但后面两次in.readLine()会直接读取下一行输入,完全偏离了你的逻辑。这也是你无法正确获取用户输入数字的重要原因。

3. 鲁棒的数字提取方案

不要用substring(table.length()-1)这种脆弱的方式提取数字——当输入包含乱码或多余字符时,这种方法很容易失效。改用正则表达式提取输入中的所有数字序列,确保能准确获取用户输入的数字:

修改桌号读取的逻辑:

sendMessageToMe("Please insert your table number:");
while (true) {
    String inputLine = in.readLine();
    if (inputLine == null) {
        // 用户断开连接
        break;
    }
    // 提取输入中的所有数字
    Pattern digitPattern = Pattern.compile("\\d+");
    Matcher matcher = digitPattern.matcher(inputLine);
    
    if (matcher.find()) {
        String numStr = matcher.group();
        int tableNumber;
        try {
            tableNumber = Integer.parseInt(numStr);
            // 验证桌号是否在有效范围(你的tables数组长度为5,索引0-4)
            if (tableNumber >= 0 && tableNumber < RestaurantTrekNation.tables.length) {
                if (RestaurantTrekNation.summmonCustomer(tableNumber)) {
                    sendMessageToMe("Your Table is ready prepare to order ");
                    this.table = numStr; // 保存正确的桌号
                    break;
                } else {
                    sendMessageToMe("Table is full please choose another table");
                }
            } else {
                sendMessageToMe(String.format("Please enter a valid table number (0-%d)", 
                    RestaurantTrekNation.tables.length - 1));
            }
        } catch (NumberFormatException e) {
            sendMessageToMe("Please enter a valid number for your table");
        }
    } else {
        sendMessageToMe("Please enter a valid table number (only digits allowed)");
    }
}

4. 额外的小问题修复

你的menu静态初始化中,08.00和09.99是无效的Java语法(以0开头的数字会被解析为八进制,但8和9不是八进制合法数字),需要修改为:

menu.add(new Dish(6, 8.00, "hello" , 5));
menu.add(new Dish(7, 9.99, "hello" , 5));

可选:过滤Telnet控制字符

如果Putty发送了Telnet协议的控制字符(比如IAC字节0xFF),这些会被当成普通字符混入输入流导致乱码。你可以在读取后过滤掉非打印字符:

// 过滤掉所有非数字、非换行的非打印字符
inputLine = inputLine.replaceAll("[^\\d\\n\\r]", "");

这些修改应该能解决你遇到的乱码和数字提取问题,同时让输入逻辑更健壮。

内容的提问来源于stack exchange,提问作者Lukas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:08:44