不同的 linux 系统版本 udp 返回的数据不同
我正在做一个程序跟 plc(具体是三菱 5u,若你不了解 plc,可以简单把它看做一个 tcp & udp 应答站) 通讯。
按照协议,我通过 udp 发送四个字节,plc 返回 14 个字节,如下:
5a00 0001 # 发送的数据
da00 0001 1400 c0a8 c826 c0a8 c826 # plc 应答的数据
随后我写了如下代码,交叉编译后运行在一台 arm 机上,
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
{
printf("socket() failed\n");
return 0;
}
struct sockaddr_in peer;
peer.sin_family = AF_INET;
peer.sin_port = htons(5560); // plc udp 端口
peer.sin_addr.s_addr = inet_addr("192.168.30.156"); // plc 目标地址
uint8_t realData[4] = {0x5a, 0x00, 0x00, 0x01};
int num = sendto(sock, realData, 4, 0, (struct sockaddr *)&peer, sizeof(peer));
if (num <= 0)
{
printf("sendto failed, num=%d, errno=%d\n", num, errno);
close(sock);
return 0;
}
printf("send to plc, num = %d, data = ", num);
for (int i = 0; i < 4; i = i + 2)
printf("%02x%02x ", realData[i], realData[i + 1]);
printf("\n");
socklen_t len = 0;
uint8_t recv_buf[1024] = {0};
ssize_t recv_len = recvfrom(sock, recv_buf, sizeof(recv_buf) - 1, 0, (struct sockaddr *)&peer, &len);
if (recv_len <= 0)
{
printf("recvfrom failed, recv_len=%d, errno=%d\n", recv_len, errno);
close(sock);
return 0;
}
printf("recv from plc, len = %d, data = ", recv_len);
for (int i = 0; i < recv_len; i = i + 2)
printf("%02x%02x ", recv_buf[i], recv_buf[i+1]);
printf("\n");
close(sock);
return 0;
}
执行结果如下:
$ ./5u
send to plc, num = 4, data = 5a00 0001
recv from plc, len = 14, data = da00 0001 1400 c0a8 468d c0a8 c826
468d 这两个字节是错的。反复执行,plc 返回的数据依然是这样。
随后在 windows 端利用 udp 调试工具,返回的结果是正确的:
程序其实很简单,协议也很简单,为什么就是错了呢?
随后我把上面的代码在虚拟机 ubuntu 14.04 编译执行了下,结果如下:
hapoa@hapoa-virtual-machine:~$ ./5ul
send to plc, num = 4, data = 5a00 0001
recv from plc, len = 14, data = da00 0001 1400 c0a8 c858 c0a8 c826
只错了一个字节:58
很奇怪,难道和系统有关,随后又把上面的代码拷贝到虚拟机 ubuntu 18.04 上,编译执行如下:
ethson@ethson-virtual-machine:~$ ./5u
send to plc, num = 4, data = 5a00 0001
recv from plc, len = 14, data = da00 0001 1400 c0a8 c826 c0a8 c826
完全正确!
怎么会和系统有关呢?有点不理解。
难道 udp 在不同(版本)的系统之间有所区别么?希望有人能指教一下,或者可以提供别的思路,谢谢。
下面是我上面验证的三个系统内核版本(分别是 arm、ubuntu 14.04、ubuntu 18.04):
# cat /proc/version
Linux version 3.10.65 (gcc version 5.3.1 20160412 (Linaro GCC 5.3-2016.05) ) #391 SMP PREEMPT Tue Dec 24 10:08:42 CST 2019
hapoa@hapoa-virtual-machine:~$ cat /proc/version
Linux version 3.13.0-24-generic (buildd@batsu) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #47-Ubuntu SMP Fri May 2 23:30:00 UTC 2014
ethson@ethson-virtual-machine:~$ cat /proc/version
Linux version 4.15.0-66-generic (buildd@lgw01-amd64-044) (gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)) #75-Ubuntu SMP Tue Oct 1 05:24:09 UTC 2019
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
plc 的返回值会根据收到的值变化而变化吗?
plc 每次收到值一样吗?
建议先抓包看下是发送方向还是接收方向不对