我正在编写一个玩具MUD客户端,它使用 TCP/IP 套接字连接到远程登录服务器。
作为 MUD 客户端的一个常见功能,我应该能够在来自服务器的响应上运行一堆正则表达式,并在它们被触发时执行一些操作。
现在,当响应很长并且在 2 个或更多 TCP/IP 数据包中收到时,就会出现问题,因此当我在响应上运行正则表达式时它们不会匹配,因为它们还没有完成(第一部分或第二部分不会单独匹配)。
所以问题是我怎么知道服务器在运行我的正则表达式之前已经完成了数据包的发送。
简短的回答是:你没有
TCP/IP 是一种串行协议,没有数据包的概念。
如果您的应用层协议使用数据包(大多数都使用),那么您有两种选择:
使用本机支持数据包的传输层(UDP、SCTP、...)
将打包信息添加到您的数据流中
添加打包信息的最简单方法是添加分隔符(通常是\n
);显然你不能在有效负载中使用分隔符,因为它已经被保留用于其他目的。
如果您需要能够在有效负载中传输任何字符(因此您不能保留分隔符),请在 TCP/IP 之上使用类似SLIP的东西
您可以保留一个堆栈,将数据包添加到其中,继续测试直到获得完整响应
如果MUD(几乎)由客户端(而不是telnet本身)播放,您可以添加分隔符,再次拥有堆栈,但不要盲目测试,在获得分隔符时进行测试。
如果您可以发送一个没有游戏效果但有来自服务器的持续回复(例如 ping)的命令,您可以将其用作各种分隔符。
你可能想多了。几乎所有的泥浆都用LF
, 分隔线\n
(一些古怪的服务器会使用CRLF
,\r\n
或什至\n\r
)。所以缓冲您的输入并扫描 delimiter \n
。当您找到一个时,将该行移出输入缓冲区,然后运行您的正则表达式。
一个特例是 telnet 命令IAC GA
,一些泥巴用它来表示提示。阅读 Telnet RFC 了解更多详细信息,https://www.rfc-editor.org/rfc/rfc854,并对泥浆特定问题进行一些研究,例如http://cryosphere.net/mud-protocol.html。
实际上,在泥泞的情况下,您将永远不会遇到排长队的问题。如果泥浆和客户之间存在很多滞后,那么您对此无能为力。