Go中用net.Dial("tcp", "host:port")即可连接Telnet服务,因其本质是TCP纯文本通信;需设读超时、手动处理\r\n换行、及时Flush,并注意IAC协商及Windows兼容性问题。

用 net.Dial 连上 Telnet 服务就完事了
Go 里没有专门的 telnet 包,但 Telnet 本质就是 TCP 上跑纯文本——直接用标准库的 net.Dial 就够。别被“Telnet”俩字吓住,它不是协议栈,只是历史遗留的交互约定(比如会发 IAC 控制字节),普通调试连这些都不用管。
实操建议:
- 用
net.Dial("tcp", "host:port")建立连接,返回net.Conn,它同时支持读写 - 如果目标服务不主动发欢迎信息(比如裸 socket 服务),
Read可能阻塞,得设超时:conn.SetReadDeadline(time.Now().Add(3 * time.Second)) - 别用
bufio.Scanner直接扫行——有些 Telnet 服务末尾不发\n,会卡死;优先用conn.Read([]byte)或带缓冲的bufio.NewReader(conn).ReadString('\n'),并手动处理截断
读写不同步?记得手动 flush 和换行
Telnet 交互是半双工感的:你发命令,它回结果,但 Go 的 net.Conn 默认不自动 flush,尤其用 fmt.Fprintf 或 bufio.Writer 写完不 Flush(),数据可能卡在缓冲区里,对方收不到。
常见错误现象:
立即学习“go语言免费学习笔记(深入)”;
- 写了命令没反应 → 忘了
conn.Write([]byte("command\r\n"))或没Flush() - 回显乱序或缺失 → 读写混用没加锁,或者并发读写同一
conn(TCP 连接不是线程安全的) - 对方只收前几个字符 → 没加
\r\n,某些 Telnet 服务严格依赖 CRLF 结束命令
实操建议:
- 写命令统一用
conn.Write([]byte("ls -l\r\n")),别依赖fmt.Fprintln的换行逻辑(它只写\n) - 如果用了
bufio.NewWriter(conn),每次写完必须调wr.Flush() - 单 goroutine 串行读写最稳;非要并发,用
sync.Mutex包住Read/Write调用
遇到 IAC、WILL、DO 怎么办
真 Telnet 服务器(如 OpenBSD telnetd)会在连接后发二进制协商包,比如 \xFF\xFD\x03(IAC DO Suppress Go Ahead),如果你直接当文本读,会看到乱码甚至解析错位。
使用场景:
- 连的是标准
telnetd服务(非自定义 TCP 服务) - 需要正确响应协商(否则可能被断连或禁用回显)
实操建议:
- 先判断是否真要处理 Telnet 协议:本地测试用
nc host port看是否输出乱码,有就说明在协商 - 简单绕过法:连上后立刻发
\xFF\xFB\x01\xFF\xFB\x03\xFF\xFD\x01(拒绝终端类型 + 回显 + 不启用代理),再开始交互 - 认真处理的话,得解析
\xFF(IAC)开头的三字节序列,跳过或响应;golang.org/x/net/telnet有参考实现,但它不维护了,慎用 - 绝大多数内部工具类 Telnet 交互(比如连 Redis 的
redis-cli -r 1模式、交换机 CLI),其实只要忽略 IAC 序列、原样转发即可
Windows 下连不上?检查换行和防火墙
Windows 自带的 telnet.exe 客户端默认用 \r\n,但有些老旧设备只认 \n;反过来,Go 客户端若发 \r\n,而服务端期待 \n,也可能卡住。
性能与兼容性影响:
- 没设
SetReadDeadline在 Windows 上更容易卡死(TCP ACK 延迟更明显) - Windows 防火墙有时会拦截非标准端口的出站连接,尤其是非管理员权限运行时
-
net.DialTimeout在 Windows 上对 DNS 解析超时不稳定,建议先用net.DefaultResolver.LookupHost分开做解析
实操建议:
- 发命令前先试
conn.Write([]byte("\n"))看是否触发欢迎屏,确认换行习惯 - 本地测试优先用
localhost或127.0.0.1,绕过 DNS 和防火墙干扰 - 抓包看第一轮交互:用
Wireshark过滤tcp.port == 23,确认 SYN 是否发出、SYN-ACK 是否收到
真正麻烦的从来不是连上或发命令,而是对方不按套路出牌:不发提示符、中途静默、突然插一段 IAC、或者用私有编码。留一手——把原始 Read 到的字节全打日志,比猜协议快得多。










