目录
思路:
- PC作为客户机,使用网络调试助手;
- LS开发板作为服务器端,部署对应程序(代码实现如下);
- 在UDP基本简单通信的基础上增加两组组播(setsockopt实现,一组也可以),实现组播通信;
- 运行服务器端程序,打开客户端向组播地址端口发送数据,此时服务器端将收到的数据发回客户端完成一次数据收发。
- setsockopt 函数介绍见:https://blog.csdn.net/liangren_/article/details/115197754
逻辑设计:
代码实现:
-
#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,
"TCP 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://blog.csdn.net/Liangren_/article/details/116029676
查看评论