树莓派双网卡场景下Python发送数据包走错误接口如何解决
问题原因
你的问题本质是系统路由策略优先级高于套接字源IP绑定,加上你eth0的子网掩码配置为0.0.0.0不符合常规局域网配置逻辑,系统无法判定189.168.200.155属于eth0直连网段,所以数据包匹配到了优先级更高的wlan0默认路由发送。
解决方案
你可以二选一实现需求:
方案1:修正网卡配置+添加静态路由(长期生效,无需改代码)
首先将eth0的子网掩码修正为正常局域网的255.255.255.0,再添加静态路由指定189.168.200.0/24网段走eth0接口,临时生效执行命令:sudo ip route add 189.168.200.0/24 dev eth0 src 189.168.200.110要永久生效可以编辑
/etc/dhcpcd.conf添加eth0的静态IP配置即可。方案2:Python代码直接指定出口接口(无需改系统配置,灵活可控)
用Linux系统套接字特有选项SO_BINDTODEVICE直接把套接字绑定到eth0接口,注意该方案需要root权限运行脚本。修改后的代码示例:import socket TCP_PORT = 3001 SERVER_IP_AD = "189.168.200.110" CLIENT_IP_AD = "189.168.200.155" BUFFER_SIZE = 1024 # 请补充你代码中缺失的该变量配置 def sendMessage(self, file_path, client_ip=CLIENT_IP_AD): print('message en route') s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 新增绑定指定出口接口 s.setsockopt(socket.SOL_SOCKET, socket.SO_BINDTODEVICE, b'eth0') s.bind((self.SERVER_IP_AD, 0)) s.connect((client_ip, self.TCP_PORT)) MESSAGE = self.openFile(file_path) s.send(MESSAGE.encode()) data = s.recv(self.BUFFER_SIZE) s.close() return data
注意事项
SO_BINDTODEVICE是Linux系统特有选项,仅适用于Linux环境,树莓派默认系统可直接使用- 采用代码绑定接口的方案时,必须用sudo运行Python脚本获取root权限,否则会抛出权限异常
- 优先建议修正eth0的子网掩码配置,
0.0.0.0的子网掩码不符合本地以太网的常规配置逻辑,会导致系统无法正常识别直连网段
内容的提问来源于stack exchange,提问作者Rudolf Fanchini
相关产品推荐
相关产品推荐

