Linux串口默认shell上的IP隧道

时间:2015-01-08 10:15:30

标签: linux serial-port ip tunnel

这是this问题的更受约束的版本:

我有一个嵌入式ARM设备运行带有Linux 3.10.0内核的自定义映像。

唯一的物理接口(不,USB,无以太网)是连接其中一个串行接口的默认Linux shell。

我的问题是:是否有任何内置或外部工具可以通过此连接打开IP隧道?

我看到一些一般问题:

  • 该设备已被Linux使用,因此必须使用stdin / out进行通信,而不是直接访问设备。
  • 启动隧道应用程序后,应用程序必须等待隧道客户端连接,因为我需要关闭计算机上的串行连接,然后启动隧道客户端。
  • 应该有办法关闭连接并返回正常的shell

实际要求是,我可以通过串行电缆从连接到嵌入式设备的计算机访问嵌入式设备上运行的REST接口。

这已经适用于具有物理以太网或USB以太网的设备,但此设备不提供此功能。

[UPDATE] 如上所述,socat目前在我们的嵌入式设备上不可用,所以作为第一次尝试,我使用了以下内容:

  • 具有物理串行接口的Linux(Ubuntu)笔记本电脑
  • 安装了物理串行接口且安装了cygwin + socat的Windows笔记本电脑
  • 两者均通过Null-modem电缆连接

注意:我一方面使用Windows笔记本电脑,因为我们将在Linux上运行socat客户端(不幸的是)。

  1. 直接STDIO连接
  2. 服务器

    socat stdio file:/dev/ttyS0,b115200
    

    客户端

    socat file:/dev/ttyS4,b115200 stdio
    

    在cygwin中,ttyS0COM1ttyS4在这种情况下为COM5

    使用这些,socat就像一个小聊天程序。为什么我在一边打字输出另一边反之亦然。

    1. TCP连接
    2. 下一步是使用TCP连接。

      服务器

      socat /dev/ttyS0,b115200,crtscts=1,raw,echo=0 tcp-connect:localhost:80
      

      客户端

      socat -T2 file:/dev/ttyS4,b115200,crtscts=1,raw,echo=0 tcp-l:7777,reuseaddr
      

      我使用硬件流控制指定了波特率(115200),使用了原始传输,没有回应(否则HTTP请求将被发送回请求者)。 Pus我不得不使用超时-T2,在2s后终止连接。否则,curl也不会终止并等待更多数据。

      当我在Windows计算机上使用curl时,它通过串行连接成功传输请求,并在Linux计算机上返回HTTP服务器的完整HTTP响应:

      curl localhost:7777/index.html
      

      但是,它只能工作一次。请求完成后,socat客户端和服务器都将终止。

      此外,当我使用浏览器(Chorme)时,它使用g-zip编码,最可能发送二进制字符。其中一个字符将是EOF字符,在完成请求/响应之前再次终止socat

      然后我尝试将fork添加到服务器:

      socat /dev/ttyS0,b115200,crtscts=1,raw,echo=0 tcp-connect:localhost:80,fork
      

      这可以使服务器保持活动状态,但curl会返回400 Bad Request。所以似乎socat服务器发起了对每个行或块的请求,因为它不了解HTTP。

      1. IP连接
      2. 然后我想到了下面一层并使用TUN连接。但是,这不是在socat的Windows版本上实现的。

        1. HTTP连接
        2. 如果我错了,请纠正我,但据我了解,socat没有提供实际理解HTTP的连接类型,并且能够通过串行连接正确地序列化它。

          所以,我找不到任何稳定的方法来启动客户端和服务器,并通过串行连接运行多个HTTP请求。

2 个答案:

答案 0 :(得分:1)

在普通的Linux上,您可以使用socat

此程序允许您连接多种流类型(文件,套接字,tcp,udp,...)。在你的情况下,它将是tcp文件或更准确地说是在端口xx到/ dev / ttyUSB1的tcp套接字。您应该在两侧启动socat来构建隧道。

编辑1:
对不起,我也对socat感到失望。我无法找到一个解决方案,可以让我的TCP侦听器在多个连续连接中保持活动状态,但一次只处理一个连接。

我的解决方案是一个使用4个线程的简单C#程序:  1.等待stdin的输入,例如退出命令  2. TCP监听器  3.用于活动连接的TCP工作线程  4.如果TCP打开,它会为COM打开另一个线程

线程3从TCP读取并写入COM,Tread 4从COM读取并写入TCP。如果线程获得TCP关闭事件,它将停止线程4,它关闭COMx,并自行退出。现在线程2可以接受新连接。如果线程1在stdin上读取exit,它会将消息传递给所有线程以停止和关闭。

也许你可以在嵌入式系统上使用pthreads在C中实现这样一个简短的程序,它没有社交。

EOF问题: 我试图谷歌搜索一个逃脱特殊字符的程序或将数据流从ASCII重新编码为ANSI或base64或其他....如果你能找到这样的程序或者也可以用C语言编写它你可以在它之间管道

Server <=> reencode <=> socat <--serial--> socat <=> reencode <=> client

答案 1 :(得分:0)

我们现在使用pppd解决了问题。事实证明,即使Windows支持ppp。与socat相比,pppd实际上使用了包含错误检测的协议,它会自动在Linux和Windows系统上创建网络设备。

唯一的问题是,pppd需要访问串行设备。没有像ppp工具提供的直接模式。

我们现在正在按需禁用shell,重新启动到IP-over-serial模式。完成后,我们重启系统,使用串行线自动切换回getty

这不是最漂亮的解决方案,但现在似乎有效。