在Linux环境下将串口数据转换为TCP/IP

33

我需要从Linux系统的串口获取数据并将其转换为TCP/IP协议发送到服务器。这个操作难吗?我有一些基本的编程经验,但对Linux不是很熟悉。是否有一个开源应用程序可以完成这个任务?


你可能会发现这个对于TCP/IP部分很有用,而串口方面你可以在这里得到很多帮助。请记住,在Linux中,一切都是“文件”,所以你可以使用“cat”命令读取串口。 - Filip Ekberg
10个回答

35

在Linux下,你不需要编写程序来实现这个功能。只需要通过管道将串口输入输出重定向到netcat即可:

netcat www.example.com port </dev/ttyS0 >/dev/ttyS0

只需要替换地址和端口信息即可。另外,您可能使用了不同的串行端口(即更改/dev/ttyS0部分)。您可以使用sttysetserial命令来更改串行端口的参数(波特率、奇偶校验、停止位等)。


2
笔误:将“< cat /dev/ttyS0”更改为“< /dev/ttyS0”。功能:可能将其放入shell脚本中 while : do netcat ... done 如果存在文件I/O结束的危险,例如如果它是调制解调器,失去载波等。 - Liudvikas Bukys
2
你可能也想看一下 socat。 - Douglas Leeder
1
太棒了!在同一设备上进行输入和输出管道的目的是什么? - devwannabe
@devwannabe,您正在指定将nectat的stdin和stdout重定向到/dev/ttyS0。因此,网络数据将传输到串行端口,反之亦然。 - Judge Maygarden
1
希望有人能编辑这个答案并解释一下 < 和 > 的逻辑,先发生了什么?它是如何工作的?也许看起来很琐碎,但我也需要对日志文件进行一些重定向,并发现这很具有挑战性... - chenchuk
显示剩余5条评论

13

我通过Google搜索找到了这个问题,它与我的问题非常相似 (在Linux客户端上通过TCP/IP使用服务器上的串口),因此,尽管这不是针对原始问题的答案,但我认为其中的一些代码可能对原始发布者有用:

  • 让带有串口的Linux机器侦听TCP端口以共享调制解调器:ser2net
  • 从另一个Linux工作站使用此“共享”调制解调器:remtty

我也是通过同样的方式到达这里的;因为提供了ser2net的链接,所以给你点赞,它看起来就是我一直在寻找的东西。 - Dennis

8
你可以使用 socat 创建串行局域网(SOL)连接。它可以用于将 ttyS“转发”到另一台计算机,以便它看起来像是本地的,或者您可以通过 TCP/IP 端口访问它。

2
根据此页面的说明,socat并不直接支持RFC 2217,但它提供了一个补丁来支持它。 - Craig McQueen
ttyS?你是想说 ttys 吗? - Peter Mortensen
如果客户端期望串行ioctl,则此方法无法正常工作。 - andyn

6

大多数现代Linux发行版已经提供了您需要的所有工具。

正如一些人指出的那样,您可以通过netcat来传输串行数据。但是您需要每次连接都重新启动一个新实例。为了在连接之间保持持久性,您可以使用以下配置创建xinetd服务:

service testservice
{
    port        = 5900
    socket_type = stream
    protocol    = tcp
    wait        = yes
    user        = root
    server      = /usr/bin/netcat
    server_args = "-l 5900 < /dev/ttyS0"
}

请确保将/dev/ttyS0更改为您尝试接口的串行设备。


3

使用netcat在服务器上打开一个端口并开始监听:

nc -lvp port number

在您正在读取串口的设备上,以root身份使用netcat将其发送:
nc <IP address> portnumber < /dev/ttyACM0

如果你想将数据存储在服务器上,你可以将数据重定向到文本文件。

首先创建一个文件来保存数据:

touch data.txt

然后开始保存数据

nc -lvp port number > data.txt

这个方法可以工作,但需要访问托管端口的机器上的终端。更健壮的解决方案是使用ser2net,其中服务器充当访问远程资源的常规服务器。当然,这种方式更加“安全”,因为您需要先使用SSH物理连接到远程系统,然后才能访问串行端口,但与此同时,它比ser2net不太方便。这有点取决于您的需求... - Matthias Hryniszak

2

TCP转串口 Systemd 服务

如果你的 Linux 机器正在运行 systemd(大多数都是这样),你可以创建一个漂亮的服务,将(USB)串行设备通过 TCP(telnet)转为可用。

安全警告:将串行设备通过TCP公开可能存在安全风险。

在本例中我使用了:

  • TCP 端口 5900
  • 串行设备 /dev/ttyUSB0(使用了两次)
  • 串行速率 115200 Bps

你可以在以下示例中编辑这些内容。查看sttync(netcat)的手册以获得更多选项。

下面所有的命令都假定你是用户root。如果不是,请执行:sudo su -

目录/etc/systemd/system应该已经存在。如果不存在,你的系统可能没有在运行Systemd。

创建文件/etc/systemd/system/tcp2serial.service并填入以下内容:

[Unit]
Description=TCP to Serial

[Service]
TTYPath=/dev/ttyUSB0
ExecStartPre=/usr/bin/stty -F /dev/ttyUSB0 speed 115200
ExecStart=/usr/bin/nc -k -l 5900
StandardInput=tty
StandardOutput=tty
Restart=always

[Install]
WantedBy=default.target

当您创建文件后,可以执行systemctl start tcp2serial命令来启动服务。

从同一网络中的另一台Linux计算机上,您可以使用telnet [server] 5900连接到它。要退出telnet,请按Ctrl+],然后键入quitEnter

当您编辑完服务文件后,请执行以下两个命令:

systemctl daemon-reload
systemctl restart tcp2serial

要让服务在开机时启动,请执行以下操作:

systemctl enable tcp2serial

2
我有同样的问题。
我不太确定开源应用程序,但我已经测试了命令行Linux下的串口以太网转换器...它对我有用。
此外,感谢Judge Maygarden的指导。

我将此答案标记为-1,因为它看起来像是商业产品的广告。也许是,也许不是——我真的不知道,但是在Linux上远程访问资源之类的事情基本上已经提供了开箱即用的功能,而且不需要任何花哨的用户界面来完成。 - Matthias Hryniszak

1

我已经为这个问题苦苦挣扎了几天。

对我来说,问题源于VirtualBox/Ubuntu。我的机器上有很多USB串行端口。当我尝试将其中一个分配给虚拟机时,它破坏了所有的串行端口 - 即主机和其他虚拟机无法再使用它们的USB串行设备。

我的解决方案是在我衣橱里偶然找到的一台netbook上设置一个独立的串行服务器。

我尝试了ser2net,并成功地将串行端口放到了线上,但remtty没有起作用。我需要将端口作为虚拟机上的tty获取。

socat完美地解决了这个问题。

这里有详细的说明:

使用socat进行远程tty(通过TCP使用tty)的示例


1

我认为你的问题不太清楚。这里有几个答案可以解决如何捕获Linux串口输入数据的问题,但也许你的问题正好相反?

如果你需要捕获从Linux串口输出的数据并将其发送到服务器,则有几个小型硬件设备可以实现此功能,从简单的串行打印服务器(例如Lantronix gizmo)开始。

不,我与Lantronix没有任何关系。


-1

你可能会发现PerlPython对于从串口获取数据非常有用。 如果要将数据发送到服务器,如果服务器是(假设)一个HTTP应用程序或者一个流行的数据库,解决方案可能很容易。但如果它是一些定制/专有的TCP应用程序,则解决方案可能不那么容易。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接