Linux串行默认shell的IP隧道

这是这个问题的一个更受限制的版本:

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

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

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

我看到一些一般问题:

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

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

这已经在具有物理以太网或USB以太网的设备上工作,但是该设备不提供这个function。

[更新]正如所解释的,socat目前在我们的embedded式设备上不可用,所以第一次尝试时,我使用了以下内容:

  • 具有物理串行接口的Linux(Ubuntu)笔记本电脑
  • 具有物理串行接口和cygwin + socat的Windows笔记本电脑
  • 两者都通过零调制解调器电缆连接

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

  1. 直接连接STDIO

服务器

socat stdio file:/dev/ttyS0,b115200 

客户

 socat file:/dev/ttyS4,b115200 stdio 

在cygwin中, ttyS0COM1 ,本例中的ttyS4COM5

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

  1. TCP连接

下一步是使用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 

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

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

 curl localhost:7777/index.html 

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

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

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

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

这使服务器保持活动状态,但curl返回400 Bad Request 。 所以看起来好像socat服务器启动了每一行或一个块的请求,因为它不理解HTTP。

  1. IP连接

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

  1. HTTP连接

纠正我,如果我错了,但据我所知, socat不提供一个连接types,实际上了解HTTP,并能够通过串行连接正确序列化。

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

在一个普通的linux上,你可以使用socat

这个程序允许你连接多种类型的流(文件,套接字,tcp,udp,…)。 在你的情况下,将tcp文件或更确切地说是一个TCP端口xx到/ dev / ttyUSB1的套接字。 你应该启动社会双方建立一个隧道。

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

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

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

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

EOF的问题:我试图谷歌一个程序,转义特殊字符或重新编码从ASCII到ANSI或base64的数据流或任何….如果你可以找到这样的程序或写在C也可以管它在之间

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

我们现在已经用pppd中途解决了这个问题。 事实证明,即使Windows支持PPP 。 与socatpppd实际上使用了一个包含错误检测的协议,它会自动在Linux和Windows系统上创建网络设备。

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

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

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