0
该例程是基于网上搜索到的实例进行修改而来的,也都是基本实例,复制粘贴的比较快速,将发送接收部分进行修改就得到下面的代码了。
先看看100ASK_STM32MP157 板子与pc连接拓扑图吧,毕竟这个是组播发送,还是需要说明一下的。
虚拟机通过桥接模式与PC连接,可以当作独立的pc,与交换机连接,
100ASK_STM32MP157通过eth1与交换机连接。
代码分别编译出100ASK_STM32MP157和Ubuntu两个版本,并分别拷贝存储起来。
下面就是两者间通讯截图。
下图是Ubuntu发生组播数据,100ASK_STM32MP157接收打印组播数据,在截图上有文字简单说明。
下图是Ubuntu接收显示组播数据,100ASK_STM32MP157发生组播数据,在截图上也有文字简单说明。
演示结果已经分享完毕,下面来看看源码部分吧。
先来看看发生组播数据的代码:
- /*send.c*/
- #include
- #include
- #include
- #include tinet/in.h>
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
- #define TRAM_STATUS_ADDR "239.0.0.30"
- #define TRAM_STATUS_RECV_PORT 9200
-
- int main(int argc, char **argv)
- {
-
- struct sockaddr_in addr, mcast_addr;
- int fd, cnt;
- struct ip_mreq mreq;
- int addrlen, num;
- char msg[80];
-
- sprintf(msg, "%s", "hello");
-
- if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- {
- perror("socket");
- return -1;
- }
-
- memset(&mcast_addr, 0, sizeof(mcast_addr));
- mcast_addr.sin_family = AF_INET;
- mcast_addr.sin_addr.s_addr = inet_addr(TRAM_STATUS_ADDR);
- mcast_addr.sin_port = htons(TRAM_STATUS_RECV_PORT);
-
- int loop = 0;
- while(1)
- {
- snprintf(msg, sizeof(msg), "%s, %drn", argv[1], ++loop);
- if (sendto(fd, (const char *)msg, sizeof(msg), 0, (struct sockaddr *)&mcast_addr, sizeof(mcast_addr)) < 0)
- {
- perror("sendto");
- return -1;
- }
- usleep(300*1000);
- }
- printf("send ok!n");
-
- setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mcast_addr, sizeof(mcast_addr));
- close(fd);
-
- return 0;
- }
复制代码
之后看看接收组播数据的代码:
- /*recv.c*/
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
- #define MSGBUFSIZE 256
- #define TRAM_STATUS_ADDR "239.0.0.30"
- #define TRAM_STATUS_RECV_PORT 9200
-
- int main()
- {
- struct sockaddr_in addr;
- int fd, nbytes, addrlen;
- struct ip_mreq mreq;
- char msgbuf[MSGBUFSIZE];
- int on;
-
- if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- {
- perror("socket ");
- return -1;
- }
- /* 初始化地址 */
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = htonl(INADDR_ANY);
- addr.sin_port = htons(TRAM_STATUS_RECV_PORT);
-
- if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
- {
- perror("bind");
- return -1;
- }
-
- on = 1;
- /* 设置地址复用许可, 根据具体情况判断是否增加此功能 */
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
- {
- perror("SO_REUSEADDR");
- return -1;
- }
-
- /*加入多播组*/
- mreq.imr_multiaddr.s_addr = inet_addr(TRAM_STATUS_ADDR);
- mreq.imr_interface.s_addr = htonl(INADDR_ANY);
- if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
- {
- perror("setsockopt");
- return -1;
- }
-
- while(1)
- {
- addrlen = sizeof(addr);
- if ((nbytes = recvfrom(fd, msgbuf, MSGBUFSIZE, 0, (struct sockaddr *)&addr, (socklen_t *)&addrlen)) < 0)
- {
- perror("recvfrom");
- return -1;
- }
- printf("recv: %s", msgbuf);
- }
- printf("recv ok!n");
-
- /*退出多播组*/
- setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));
- close(fd);
-
- return 0;
- }
复制代码
可能有的伙伴会遇到打开程序找不到设备的问题,我也把网上的解决办法贴出来了。
网上的解决办法如下:
不过这边要是连接交换机的话,可以使用udhcpc命令解决,这个效果是一致的。
本次分享到此结束,下次见。
|
|