65.9K
CodeProject 正在变化。 阅读更多。
Home

Windows Mobile Telnet 客户端

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (9投票s)

2007年8月5日

CPOL

8分钟阅读

viewsIcon

66981

downloadIcon

2701

为 Windows Mobile 5 设备实现的 Telnet 客户端。

Screenshot - ConnectionSetting.png

引言

如今,我主要将 telnet 用作 HTTP、SMTP 和其他协议的诊断工具。我自己经常使用它来诊断服务器问题。最近,我发现我的手机是使用 telnet 进行这些用途的理想设备,因为它不仅可以轻松连接到本地网络进行测试,还可以利用其唯一的互联网连接从本地网络外部连接到服务器。

使用 C# 和 .NET Compact Framework,我仅用不到一天的时间就快速轻松地编写了这个客户端。在本文档中,我将重点介绍创建客户端最重要的部分。

必备组件

编写此应用程序时,我以 Windows Mobile 5 Professional 设备为目标。我在 HTC Wizard(品牌为 Cingular 8125)和 iPaq 4705 上测试了该程序。我曾尝试在 Motorola Q 上运行该程序,但未能解决出现的与线程相关的异常(不幸的是,此异常还会导致 Visual Studio 关闭)。因此,目前我认为该程序尚不能在没有触摸屏的设备上运行。要运行此程序,您的设备必须安装 2.0 Compact Framework。如果尚未安装,Visual Studio 会在您允许 Visual Studio 在您的 Windows Mobile 5 设备上调试程序时将其安装到您的设备上。

UI 的设计能够显示在分辨率为 240x240 的设备上,但最好在分辨率至少为 320x240 的设备上运行。如果使用了部分实现的终端模拟器功能,最好在 VGA 分辨率设备上运行。

并非所有设备都相同

.NET 允许该程序在多种设备上运行。不幸的是,我发现并非所有运行该框架的设备都支持 .NET 2.0 Framework 的所有功能。更复杂的是,即使您使用了不受支持的功能,IDE 也不会生成错误(而且我无法现实地期望它做到,因为它无法知道它将运行的所有设备的全部功能)。

一个不会在所有设备上工作的示例功能是 ToolBar 控件。此控件在桌面和 Windows Mobile 5 Professional 设备上都能正常显示,但在 Moto Q 上会引发 UInsupportedException。我还发现“保存文件对话框”在两个平台都不可用。

建立连接

建立 telnet 会话的所有代码都包含在 TelnetSession 类中。该类中主要的感兴趣对象是 Socket 类和 NetworkStream 类的实例。套接字的创建在 CreateSocket 方法中完成。此方法以目标机器的地址或主机名以及要使用的远程端口号作为其参数。该方法解析目标机器的 IP 地址并尝试与其建立连接。如果成功,将返回创建的套接字。

Socket CreateSocket(string machineAddress, int port)
{    
    //Resolve the IP address(es) of the target machine
    IPHostEntry iphostEntry = null;
    iphostEntry = Dns.GetHostEntry(machineAddress);
    //let's go through the list of IP addresses returned and attempt
    //to connect to each one.  once a successful connection is made
    //return the socket created from that connection and stop testing
    //on any remaining ports.  If no connection can be established then 
    //return null
    foreach (IPAddress address in iphostEntry.AddressList)
    {
        IPEndPoint ipe = new IPEndPoint(address.Address, port);
        Socket tempSocket = new Socket
		(ipe.AddressFamily,SocketType.Stream, ProtocolType.Tcp);
        tempSocket.Connect(ipe);
        if (tempSocket.Connected)
        {
            return tempSocket;
        }
    }
    return null;
}

创建套接字后,会将一个 NetworkStream 对象封装在其周围,以便我们拥有套接字的流接口。然后创建 StreamReader StreamWriter ,它们引用网络流,并为我们提供与连接交互的自然方式。

读写数据

向连接写入数据非常简单。使用 StreamWriter 对象上的 Write 方法将字节数组通过流发送。

public void Send(byte[] message)
{
    _writerStream.Write(message);
    _writerStream.Flush();
}

读取数据稍微复杂一些。虽然可以调用 StreamReader.Read 方法,但这是不理想的,因为它会阻塞线程直到读取缓冲区已满。如果服务器返回少量字节,程序可能会卡住并等待更多字节,即使没有更多字节。由于连接的异步性质,我们不知道将接收多少字节以及何时接收。

为了解决不知道何时接收数据的问,会创建一个新线程,该线程将等待数据接收并将在数据可用时触发事件。在线程中,会检查 NetworkStream 对象的 DataAvailable 属性。如果没有数据可用,线程只会休眠一段时间。如果数据可用,则会立即读取并转换为 string。此 string 会添加到队列中,然后 TelnetSession 对象通过 BlockReceived 事件发送通知,以告知订阅者数据可用。生成的 string 通过 ReadBlock 方法读取。请注意,ReadBlock 返回任意行数的文本。

发生此情况的线程被标记为后台线程。这有助于确保在应用程序的主线程终止时终止该线程。否则,用户关闭程序但程序继续运行的风险就会存在。

向用户显示信息

该程序支持两种向用户显示信息的方式。第一种(也是最简单)的方式是将接收到的 string 直接写入 textbox。由于 Windows Mobile 设备可能内存有限,随着更多信息添加到 textbox 中,文本会从 textbox 的开头被删除,以限制其大小。对于大多数 telnet 会话,这将是一种足够的显示技术。

第二种显示数据的方式涉及程序中一个名为 TelnetTerminal 的类。此类模拟了具有固定宽度和高度的显示终端的行为。我将终端设置为 80 列宽度和 25 行高度(这些尺寸可以通过对象的构造函数进行更改)。终端可以识别某些转义序列,用于在其内部移动光标和清屏。虽然 TerminalEmulator 类受到 Ecma 48 的启发,但它远非完整实现。该终端在很大程度上是实验性的,但仍保留在程序中,供任何希望扩展其功能的人使用。TerminalEmulator 在 VGA 功能的 Windows Mobile 设备上效果最佳。

输入和保存连接信息

连接信息通过 ConnectionSettings 窗体输入。该窗体询问要连接的机器名称、要使用的端口、是否缓冲输入以及其他一些内容。这些信息的详细信息如下所示。

  • 连接名称 – 为连接指定的名称
  • 地址 – 目标机器的机器名称或 IP 地址
  • 端口 – 用于建立连接的远程端口
  • 缓冲输入 – 如果启用,将允许输入累积到 textbox 中,并在按下回车键时一次性发送所有文本。否则,每次按键都会立即传输。
  • 本地回显 – 如果启用,所有传输的信息将立即显示在终端屏幕上。
  • 终端类型 – 允许用户选择简单的终端界面(字符缓冲区)或实验性终端界面(终端模拟器,在 VGA 功能的设备上使用效果最佳)。

可以通过菜单序列 文件->新建连接 访问该窗体。创建新连接时,当前连接的信息将用于填充每个字段的默认值。保存的连接信息会被序列化到 XML 文件中,因此您也可以使用文本编辑器轻松更改连接信息。

运营商限制

在测试此程序时,我确实发现在使用某些电话运营商时,我无法通过某些端口打开连接。需要注意的是,您的运营商可能不允许使用所有端口。

三种调试方法

有三种方法可以调试此程序。推荐的方法是将您的 Windows Mobile 5 设备连接到计算机,然后按 F5 开始部署和运行应用程序。您会看到一个屏幕,允许您选择目标设备。标有“Windows Mobile 5.0 Pocket PC Device”的第一项会视需要将程序和 .NET Compact Framework 复制到您的设备上。第二种方法是从程序部署时选择其中一个模拟器。

Screenshot - WM5_Selection.png

第三种测试方法是在您的工作站上运行该程序,并在 Visual Studio 中附加到它。为此,请编译程序,然后导航到最终二进制文件存储的位置。运行它,然后在 Visual Studio 中,选择菜单序列 调试->附加到进程。然后,您可以选择 J2i.Net.Telnet.exe 作为要附加和调试的进程。

调试 HTTP 请求

最简单的调试连接将是 HTTP 请求。为此,请创建一个新连接,并将 Web 服务器名称指定为地址(例如 www.microsoft.com),将端口设置为 80,并选择“字符缓冲区”终端类型。选择“确定”后,会启动会话。输入 GET /,然后按两次回车键。您应该会收到服务器对其根页面的原始响应。

结论和未来功能

我相信,在当前形式下,该程序作为诊断工具是很好的。如果需要或要求,我以后可能会决定添加记录会话中发送的信息的功能,或者进一步实现终端模拟器功能。我计划进一步研究导致应用程序在 Motorola Q 上运行失败的原因。我还可能添加用户界面,以允许自定义终端的属性(例如文本颜色)。

历史

  • 2007 年 8 月 5 日 - 文章发布
© . All rights reserved.