问题背景
这是我在做海草移植项目过程中需要实现的功能——使用电力载波连接Jetson Nano与Raspberry实现信息互通,写下此篇博客以作记录
一、TCP通信
1.1 简单介绍
TCP协议,传输控制协议(英语:Transmission Control Protocol,缩写为:TCP)是一种面向连接的、可靠的、基于字节流的通信协议。
TCP把连接作为最基本的抽象单元,每条TCP连接有两个端点,TCP连接的端点即套接字。
套接字: socket = (IP地址 + 端口号)
TCP连接:{socket1, socket2}={(IP1:port1), (IP2:port2)}
TCP提供全双工通信。
详细解释可参考网上资料。
1.2 一般用法
进行TCP通信的两端设备必须要在同一区域网或者网段内。如果使用的是无线网(WiFi),那么只需要将双方设备连接到同一WiFi上即可;如果使用的是以太网(网线),需要通过一根网线将双方设备接在一起,同时配置两端设备的静态以太网IP(eth0),使其处于同一网段。
二、电力载波
2.1 简单介绍
本款电力载波模块由ROVMaker官方售卖,其可通过电力线传输以太网信号,实现最长300米高速通信。由于传统双绞线不适合远距离传输以太网信号且干扰能力弱,所以此类工况下通常需要高频信号进行通信。 本公司所生产电力载波通信模块可通过L/N电力线进行高频通信,传输速率高(300m传输距离,统一电表范围内,实测可达100Mbps),最多支持8个节点,工作稳定,抗干扰能力强,操作方便快捷。
2.2 一般用法
电力载波模块供电电压为DC12V,工作组网时需要成对使用,L接L,N接N,用来建立长距离网络通信。
首先把电力载波模块的网线插入电脑,电力载波模块是以太网透传,两个电力载波模块如下图连接后,相当于一段网线。
三、以太网-静态ip配置
受限于电力载波的使用要求,我们只能选择通过以太网方式实现TCP通信。以下是具体实现过程:
3.1 Jetson Nano相关配置
- 首先终端输入ifconfig,查看相关网络信息。重点关注eth0(即以太网)网络信息。
- 如果看见其有ipv4地址信息,则无需再进行配置。否则,按下述操作进行
- 修改网络配置文件:/etc/network/interface。使用命令:
sudo nano /etc/network/interface
- 添加以下内容:
auto eth0 iface eth0 inet static address 192.168.137.123 netmask 255.255.255.0 gateway 192.168.137.1 dns-nameserver 114.114.114.114
- 按ctrl+u进行保存,随后按enter键确认保存文件信息,最后按ctrl+x退出。
- 随后可以使用命令开启eth0设备。使用命令:
sudo ifup -v eth0
- 最后重启设备(使用命令:
sudo reboot
)后,再次输入ifconfig即可查看到eth0设备的静态固定ipv4地址信息。
3.2 Raspberry相关配置
- 首先终端输入ifconfig,查看相关网络信息。重点关注eth0(即以太网)网络信息。
- 如果看见其有ipv4地址信息,则无需再进行配置。否则,按下述操作进行
- 修改网络配置文件:/etc/network/interface。使用命令:
sudo nano /etc/network/interface
- 添加以下内容:
auto eth0 iface eth0 inet static address 192.168.137.111 netmask 255.255.255.0 gateway 192.168.137.1 dns-nameserver 114.114.114.114
- 按ctrl+u进行保存,随后按enter键确认保存文件信息,最后按ctrl+x退出。
- 随后可以使用命令开启eth0设备。使用命令:
sudo ifup -v eth0
- 最后重启设备(使用命令:
sudo reboot
)后,再次输入ifconfig即可查看到eth0设备的静态固定ipv4地址信息。
3.3 配置注意事项
由上可以发现,Jetson Nano与Raspberry的配置步骤是一致的,二者唯一的区别在于/etc/network/interface文件中的address不同。当前我的理解是二者必须要配置在同一个网段中,即ipv4中前24位是网络号、后8位是主机号。我们可以有两种选择,一是将两个设备的网络号统一设置,主机号有所区别;二是两个设备的网络号不统一,网关(gateway)统一设置。
3.4 TCP通信Python代码
- 服务端-Raspberry:
from socket import * IP = '0.0.0.0' PORT = 50000 BUFLEN = 512 listenSocket = socket(AF_INET, SOCK_STREAM) listenSocket.bind((IP, PORT)) listenSocket.listen(5) print(f"服务端启动成功,在{PORT}端口等待客户端连接...") dataSocket, addr = listenSocket.accept() print("接收一个客户端连接:", addr) while True: receved = dataSocket.recv(BUFLEN) if not receved: break info = receved.decode() print(f"收到对方信息: {info}") dataSocket.send(f"服务端收到了信息:{info}".encode()) dataSocket.close()
- 客户端-Jetson Nano:
from socket import * IP = '192.168.137.111' SERVER_PORT = 50000 BUFLEN = 512 dataSocket = socket(AF_INET, SOCK_STREAM) dataSocket.connect((IP, SERVER_PORT)) while True: toSend = input('>> ') if toSend == 'exit': break dataSocket.send(toSend.encode()) receved = dataSocket.recv(BUFLEN) if not receved: break print(receved.decode()) dataSocket.close()
3.5 注意事项
如果你的Raspberry或者Jetson nano还需要联网,那么在3.1、3.2进行/etc/network/interface文件配置时,取消gateway设置即可。