我有一个最简单的C#程序,它从NetworkStream读取字节并将它们的文本表示发回:

using System.Net;
using System.Net.Sockets;
using System.Text;

var listener = new TcpListener(IPAddress.Any, 5050);
listener.Start();

var client = listener.AcceptTcpClient();
var stream = client.GetStream();
int b;
while ((b = stream.ReadByte()) != -1) {
    var str = $"{(byte)b:x2} ";
    Console.Write(str);
    stream.Write(Encoding.ASCII.GetBytes(str));
}

例如,如果我telnet到localhost 5050并写入hello<enter>,我得到68 65 6c 6c 6f 0d 0a.

只要我在telnet窗口中按下Ctrl-C,程序就会在其控制台窗口中 echo ff f4 ff fd 06,但telnet客户端没有收到任何消息.之后,我在telnet客户端中输入的任何其他内容也会在程序的控制台中 echo ,但telnet客户端永远不会接收到.这发生在WSL2 Ubuntu或MSYS2的telnet上.

Native Windows Telnet客户端工作正常(实际上使用Ctrl-C表示为03的情况下逐个字符发送数据).

推荐答案

您看到的是(Linux)终端与telnet客户端和协议的交互

当您在Linux(包括WSL)终端窗口1中点击ctrlC时,它会向该终端中运行的前台进程发送SIGINT.如果该进程是Telnet客户端,它将捕获该信号并将Telnet中断进程命令(ff f4)发送到它正在与之对话的任何"服务"(在本例中是您的简单C#程序)

当您在本地Windows终端中点击ctrlC时,它只发送一个03 ascii字符(ETX).

因此,为了处理这个问题,您可以扩展您的简单程序以理解(一些)Telnet协议命令.这里总结了该协议的工作原理on wikipedia,但基本上归结为识别输入中的0xff字节,然后根据后面的一个或多个字节执行一些操作.


1这是"正常"行为,但它确实取决于终端模式.如果终端被置于"原始"模式,所有特殊字符处理和信令将被禁用,ctrlC将仅发送ASCII代码3(ETX)

Linux相关问答推荐

如果在两种模式之间找到文本,则使用sed删除它们之间的所有行

命令行中使用`..`为什么会导致权限被拒绝错误?

如何在 ERE 中结束这个正则表达式

bind(): "无法分配请求的地址"

awk/sed 命令仅在模式 2 匹配时打印模式 1

从 Ansible 中的 shell 命令输出中提取特定数据

如何使用awk或其他方法提取双引号中的子字符串?

如何判断 Linux 机器是否支持 AVX/AVX2 指令?

Linux/Unix 手册页语法约定

如何使用多个版本的 GCC

如何使用完整路径或文件名显示 grep 结果

在 Ubuntu 上运行自包含的 ASP.NET Core 应用程序

*nix 系统上是否有与 COM 等效的功能?如果不是,那么 *nix 的可重用性方法是什么?

从bash中的字符串中删除所有特殊字符和大小写

命令行 Arduino 编译和上传?

如何将路径名中的..转换为 bash 脚本中的绝对名称?

比较文件的日期 bash

判断环境变量是否已经设置

Docker:您是否try 连接到没有 TLS 的启用 TLS 的守护进程?

如何通过 xmllint 使用 XSD 验证 XML 文件