c++ - 实现 TCP 应用程序内置 shell 的简单方法

标签 c++ c shell sockets tcp

我想将我自己的 shell 嵌入到我的 C++ 可移植应用程序中,它可以通过 TCP 访问。问题是我真的不知道如何处理控制字符,例如退格键、转义符……我应该考虑实现 telnet 协议(protocol)吗?有什么简单的方法可以解决这个问题?

注意:

我知道我正在回避“基于意见”的关闭理由,但也许存在一种“规范”的方式,它被广泛用于解决这个问题。

最佳答案

如果您的目标是实现一个功能齐全的 telnet 服务器(即类似于 Linux 提供的服务器,它可以运行任意命令行程序并可以正确处理用户可能想要运行的任何内容,包括伪 GUI 程序,例如NetHack),那么您将别无选择,只能实现大部分或全部 RFC 854 . telnet 协议(protocol)并非微不足道,但它比许多协议(protocol)都简单,因此实现它可能并不像您想象的那么困难。

另一方面,如果您不需要“完全的 telnet 兼容性”,而只是想为用户提供一种登录您的程序、向其发送文本命令并读回结果的方式,那就是容易得多——只需让您的程序在一个众所周知的端口上接受 TCP 连接(它甚至可以是默认的 telnet 端口 23,尽管这会排除在该端口上运行标准的 telnet 守护程序)。您的程序可以简单地通过接受的 TCP 连接发送和接收 ASCII 字符串,这或多或少可以与任何 telnet 客户端一起工作,因为 telnet 协议(protocol)被设计为优雅地降级,因此即使在以下情况下仍然可以在基本模式下工作连接一端的程序不响应任何 telnet 的特殊命令代码。

盲目地从 telnet 客户端接收字节的一个小问题是来自 telnet 客户端的任何命令代码可能会混淆您的文本解析器。如果这对你来说是个问题,你可以做这样的事情来从 recv() 的数据中过滤掉它们,就在你将该数据缓冲区移交给程序的文本解析例程之前:

// Rewrites a C character buffer in-place to remove any telnet command-codes from it
// @param buf Pointer to a buffer of data bytes just recv()'d from the telnet client
// @param bufLen The number of valid bytes that (buf) is pointing to
// @returns the number of valid data bytes that (buf) is pointing to after control codes were removed 
int FilterInputBuffer(char * buf, int bufLen)
{
   // persistent state variables, for the case where a telnet command gets split
   // up across several incoming data buffers
   static bool _inSubnegotiation = false;
   static int _commandBytesLeft = 0;

   // Based on the document at http://support.microsoft.com/kb/231866
   static const unsigned char IAC = 255;
   static const unsigned char SB  = 250;
   static const unsigned char SE  = 240;

   char * output = buf;
   for (int i=0; i<bufLen; i++) 
   {
      unsigned char c = buf[i];
      bool keepChar = ((c & 0x80) == 0);
      switch(c)
      {
         case IAC: _commandBytesLeft = 3;                            break;
         case SB:  _inSubnegotiation = true;                         break;
         case SE:  _inSubnegotiation = false; _commandBytesLeft = 0; break;
      }
      if (_commandBytesLeft > 0) {--_commandBytesLeft; keepChar = false;}
      if (_inSubnegotiation) keepChar = false;
      if (keepChar) *output++ = c;  // strip out any telnet control/escape codes
   }
   return (output-buf);  // return new (possibly shorter) data-buffer length
}

关于c++ - 实现 TCP 应用程序内置 shell 的简单方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24699661/

相关文章:

c - 为什么 Clang 会看到类型冲突?

linux - 空格出现在 linux 的 https url 中

linux - 查找在特定日期从特定计算机登录的所有用户

c++ - 不安全的模板数组构造函数

c++ - 存储非拥有引用的对象,在销毁引用之前必须通知该引用

c - 错误 : attempt to use poisoned "SIG_OUTPUT_COMPARE0A"

c - 切换大小写表达式

c++ - 将磁贴添加到 MFC 应用程序

c++ - 使用指针会导致内存堵塞吗?

linux - 参数扩展