SylixOS组播使用

来源:互联网 发布:台达plc编程入门 编辑:程序博客网 时间:2024/06/11 01:33

1. 概述

      本文主要介绍如何在SylixOS上使用组播功能。

2. SylixOS组播设置

       组播传输,即在发送者和每一接收者之间实现点对多点网络连接通信。正常大家会参考Linux使用组播的方法:把本机加入组播地址,即本机网卡作为组播成员,只有加入组才能收到组播消息。通过setsockopt设置加入组播,这样便可以接收组播信息。Linux参考代码如程序清单 2.1和程序清单 2.2所示。

程序清单 2.1  mcastserver

#include<sys/types.h>

#include<sys/socket.h>

#include<arpa/inet.h>

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<netdb.h>

#include<errno.h>

#define BUFLEN 255

intmain(intargc, char **argv)

{

struct   sockaddr_in  peeraddr;

struct   in_addr      ia;

int                     sockfd;

char                    recmsg[BUFLEN + 1];

unsignedint           socklen,n;

struct   hostent      *group;

struct   ip_mreq       mreq;

/*

* 创建 socket用于UDP通讯

*/

sockfd =socket(AF_INET,SOCK_DGRAM, 0);

if (sockfd < 0) {

printf("socket creating err in udptalk\n");

exit(1);

}

/*

* 设置要加入组播的地址

*/

bzero(&mreq,sizeof(struct ip_mreq));

if (argv[1]) {

if ((group =gethostbyname(argv[1])) == (struct hostent *) 0) {

perror("gethostbyname");

exit(errno);

}

} else {

printf(

"you should give me a group address,

224.0.0.0-239.255.255.255\n");

exit(errno);

}

bcopy((void *)group->h_addr, (void *) &ia,group->h_length);

/*

设置组地址

*/

bcopy(&ia, &mreq.imr_multiaddr.s_addr,sizeof(struct in_addr));

/*

* 设置发送组播消息的源主机的地址信息

*/

mreq.imr_interface.s_addr =htonl(INADDR_ANY);

/*

* 把本机加入组播地址,即本机网卡作为组播成员,只有加入组才能收到组播消息

*/

if (setsockopt(sockfd,IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,

sizeof(struct ip_mreq)) == -1) {

perror("setsockopt");

exit(-1);

}

socklen =sizeof(struct sockaddr_in);

memset(&peeraddr, 0,socklen);

peeraddr.sin_family =AF_INET;

if (argv[2]) {

peeraddr.sin_port =htons(atoi(argv[2]));

}

else {

peeraddr.sin_port =htons(7838);

}

if (argv[1]) {

if (inet_pton(AF_INET,argv[1], &peeraddr.sin_addr) <= 0) {

printf("Wrong dest IP address!\n");

exit(0);

}

} else {

printf("no group address given, 224.0.0.0-239.255.255.255\n");

exit(errno);

}

/*

* 绑定自己的端口和IP信息到socket

*/

if (bind(sockfd, (struct sockaddr *) &peeraddr,sizeof(struct sockaddr_in)) == -1) {

printf("Bind error\n");

exit(0);

}

/*

* 循环接收网络上来的组播消息

*/

for (;;) {

bzero(recmsg,BUFLEN + 1);

n =recvfrom(sockfd,recmsg, BUFLEN, 0, (struct sockaddr *) &peeraddr,

&socklen);

if (n < 0) {

printf("recvfrom err in udptalk!\n");

exit(4);

} else {

/*

* 成功接收到数据

*/

recmsg[n] = 0;

printf("peer:%s",recmsg);

}

}

return 0;

}

程序清单 2.2  mcastclient

#include<sys/types.h>

#include<sys/socket.h>

#include<arpa/inet.h>

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#define BUFLEN 255

intmain(intargc, char **argv)

{

struct sockaddr_inpeeraddr, myaddr;

intsockfd;

charrecmsg[BUFLEN + 1];

unsignedint socklen;

/*

* 创建 socket用于UDP通讯

*/

sockfd =socket(AF_INET,SOCK_DGRAM, 0);

if (sockfd < 0) {

printf("socket creating error\n");

exit(1);

}

socklen =sizeof(struct sockaddr_in);

/*

* 设置对方的端口和IP信息

*/

memset(&peeraddr, 0,socklen);

peeraddr.sin_family =AF_INET;

if (argv[2]) {

peeraddr.sin_port =htons(atoi(argv[2]));

} else {

peeraddr.sin_port =htons(7838);

}

if (argv[1]) {

/*

* 注意这里设置的对方地址是指组播地址,而不是对方的实际IP地址

*/

if (inet_pton(AF_INET,argv[1], &peeraddr.sin_addr) <= 0) {

printf("wrong group address!\n");

exit(0);

}

} else {

printf("no group address!\n");

exit(0);

}

/*

* 设置自己的端口和IP信息

*/

memset(&myaddr, 0,socklen);

myaddr.sin_family =AF_INET;

if (argv[4]) {

myaddr.sin_port =htons(atoi(argv[4]));

} else {

myaddr.sin_port =htons(23456);

}

if (argv[3]) {

if (inet_pton(AF_INET,argv[3], &myaddr.sin_addr) <= 0) {

printf("self ip address error!\n");

exit(0);

}

} else

myaddr.sin_addr.s_addr =INADDR_ANY;

/*

* 绑定自己的端口和IP信息到socket

*/

if (bind(sockfd, (struct sockaddr *) &myaddr,sizeof(struct sockaddr_in))

== -1) {

printf("Bind error\n");

exit(0);

}

/*

* 循环接受用户输入的消息发送组播消息

*/

for (;;) {

/*

* 接受用户输入

*/

bzero(recmsg,BUFLEN + 1);

if (fgets(recmsg,BUFLEN, stdin) == (char *)EOF) {

exit(0);

}

/*

* 发送消息

*/

if (sendto(sockfd,recmsg, strlen(recmsg), 0,(struct sockaddr *)

&peeraddr,sizeof(struct sockaddr_in))< 0) {

printf("sendto error!\n");

exit(3);

}

printf("'%s' send ok\n",recmsg);

}

return 0;

}

    把Linux的组播程序移植到SylixOS上编译,导入运行SylixOS的板卡上,运行结果如图 2.1所示。

                  

图 2.1  组播运行结果

    根据图 2.1所示mcastclient组播信息没有被mcastserver接收到,而该测试代码在Linux上运行正常。经过分析发现Linux在网络协议栈中默认打开IP_MULTICAST_LOOP,即允许组播进行本地回环通信,而SylixOS的网络协议栈默认没有打开该选项。所以在SylixOS的组播代码中添加使用setsockopt设置IP_MULTICAST_LOOP,即允许组播本地回环的选项。在mcastclient程序中添加代码如程序清单 2.3所示。

程序清单 2.3  setsockopt设置

intloop = 1;

if (setsockopt(sockfd,IPPROTO_IP, IP_MULTICAST_LOOP, &loop,sizeof(loop)) == -1) {

perror("setsockopt");

exit(-1);

}

    重新编译mcastclient上传运行,结果如图 2.2所示。

                

图 2.2  组播运行正常



3. 参考资料

《RealEvo-IDE使用手册》

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 三门峡大坝风景区 钱塘江潮水撞击大坝瞬间 河源新丰江水库大坝 宜昌东站到三峡大坝 食戟之美食大作战 坟蛋 爷爷的坟对谁的影响大 坟土荒草是女孩子照片 烧错坟遇到鬼 怪坡 大坪医院 重庆大坪 大坪 大坪镇 大坪租房 大坪招聘 大坪中医院 大坪房产 大坪帮 重庆大坪医院 大坪医院网上预约挂号 重庆大坪医院预约挂号 大坪医院眼科 大坪医院电话 重庆大坪医院眼科如何 大坪红楼医院 大坪时代天街花店 重庆大坪医院地址 重庆大坪花店 大坪医院妇科怎么样 重庆大坪医院挂号 重庆大坪租房 重庆合川房价 兴宁死老鼠打大坪所长 娘们真浪三垌全开 阳西大垌山净业寺 垌怎么读 麻垌荔枝 大城小爱 大城 大城小事