大家好,欢迎来到IT知识分享网。
目录
思路:
- PC作为客户机,使用网络调试助手;
- LS开发板作为服务器端,部署对应程序(代码实现如下);
- 在UDP基本简单通信的基础上增加两组组播(setsockopt实现,一组也可以),实现组播通信;
- 运行服务器端程序,打开客户端向组播地址端口发送数据,此时服务器端将收到的数据发回客户端完成一次数据收发。
- setsockopt 函数介绍见:setsockopt 函数使用及选项介绍_动感超人_Crush-CSDN博客_setsockopt函数
逻辑设计:
代码实现:
#include <stdio.h>
#include <sys/socket.h>
#define __PORT_SERVER 8101 /* 服务器端口号 */
#define GROUP_ADDR_01 "224.100.200.1" /* 组播端口号 1 */
#define GROUP_ADDR_52 "224.100.200.52" /* 组播端口号 2 */
int main (int argc, char **argv)
{
int iRet = -1; /* 操作结果返回值 */
int sockFd = -1; /* socket 描述符 */
struct sockaddr_in sockaddrinRemote; /* 远端地址 */
struct sockaddr_in sockaddrinLocal;
struct ip_mreq mreq;
socklen_t uiAddrLen = sizeof(struct sockaddr_in);
char cRecvBuff[257] ={0};
register ssize_t sstRecv = 0; /* 接收到的数据长度 */
/*
* 创建 socket 连接
*/
sockFd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sockFd < 0) {
fprintf(stderr, "create socket error.\n");
return (-1);
}
/*
* 增加地址复用
*/
iRet = setsockopt(sockFd, SOL_SOCKET, SO_REUSEADDR, &iRet, sizeof(iRet));
if (iRet < 0) {
fprintf(stderr, "setsockopt SO_REUSEADDR error.\n");
return (-1);
}
/*
* 初始化本地地址信息
*/
memset(&sockaddrinLocal, 0, sizeof(sockaddrinRemote)); /* 清空地址信息 */
sockaddrinLocal.sin_len = sizeof(struct sockaddr_in); /* 地址结构大小 */
sockaddrinLocal.sin_family = AF_INET; /* 地址族 */
sockaddrinLocal.sin_port = htons(__PORT_SERVER); /* 绑定服务器端口 */
sockaddrinLocal.sin_addr.s_addr = INADDR_ANY;
/*
* 绑定本地地址与端口
*/
iRet = bind(sockFd, (struct sockaddr *)&sockaddrinLocal, sizeof(sockaddrinLocal));
if (iRet < 0) { /* 绑定操作失败 */
close(sockFd); /* 关闭已经创建的 socket */
fprintf(stderr, "UDP echo server bind error.\n");
return (-1); /* 错误返回 */
}
/*
* 多播结构体初始化
*/
mreq.imr_multiaddr.s_addr = inet_addr(GROUP_ADDR_01); /* 多播组的IP地址 */
mreq.imr_interface.s_addr = htonl(INADDR_ANY); /* 加入的客服端主机IP地址 */
if (setsockopt(sockFd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) {
perror("setsockopt");
exit(-1);
}
mreq.imr_multiaddr.s_addr = inet_addr(GROUP_ADDR_52); /* 多播组的IP地址 */
if (setsockopt(sockFd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) {
perror("setsockopt");
exit(-1);
}
while(1)
{
memset(cRecvBuff, 0, sizeof(cRecvBuff));
/*
* 从远端接收数据
*/
sstRecv = recvfrom(sockFd, (void *)&cRecvBuff[0], 257, 0, (struct sockaddr *)&sockaddrinRemote,&uiAddrLen);
if (sstRecv <= 0) { /* 接收数据失败 */
if ((errno != ETIMEDOUT ) && (errno != EWOULDBLOCK)) { /* 非超时与非阻塞 */
close(sockFd); /* 关闭已经创建的 socket */
fprintf(stderr, "UDP echo server recvfrom error.\n");
return (-1);
}
continue;
}
sendto(sockFd, (const void *)&cRecvBuff[0], sstRecv, 0, (const struct sockaddr *)&sockaddrinRemote, uiAddrLen);
}
/*
* 多播关闭
*/
setsockopt(sockFd, IPPROTO_IP, IP_DROP_MEMBERSHIP,&mreq, sizeof(mreq));
return (0);
}
运行结果:
224.100.200.1 多播组:
224.100.200.52 多播组:
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/14025.html