广播的搭建
广播的服务器
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ERR_MSG(msg) \
do \
{ \
fprintf(stderr, "line:%d", __LINE__); \
perror(msg); \
} while (0)
#define IP "192.168.0.255" // 广播IP地址,广播地址:有效网络号 + 全是1的主机号
#define PORT 1562
char buf[128] = ""; // 用来存客户端发送的信息
int main(int argc, const char *argv[])
{
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sfd < 0)
{
ERR_MSG("socket");
return -1;
}
printf("socket success\n");
// 填充地接收方自身的址信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET; // 必须填写AF_INET
sin.sin_port = htons(PORT); // 端口号的网络字节序
sin.sin_addr.s_addr = inet_addr(IP); // 广播IP地址
// 绑定bind
if (bind(sfd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
ERR_MSG("bind");
return -1;
}
// 数据包是谁发过来的
struct sockaddr_in cin;
socklen_t addrlen = sizeof(cin);
ssize_t res = 0;
while (1)
{
bzero(buf, sizeof(buf));
res = recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr *)&cin, &addrlen);
if (res < 0)
{
ERR_MSG("recvfrom");
return -1;
}
printf("[%s:%d] newfd=%d: %s __%d__\n",
inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), sfd, buf, __LINE__);
}
close(sfd);
return 0;
}
广播客户端
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ERR_MSG(msg) \
do \
{ \
fprintf(stderr, "line:%d", __LINE__); \
perror(msg); \
} while (0)
#define IP "192.168.0.255" // 广播IP地址
#define PORT 6666
char buf[128] = ""; // 用来存客户端发送的信息
int main(int argc, const char *argv[])
{
//创建套接字
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sfd < 0)
{
ERR_MSG("socket");
return -1;
}
printf("socket success\n");
//设置允许广播
int broad = 10;
if(setsockoppt(sfd, SOL_SOCKET, SO_BROADCAST, &broad, sizeof(broad)) < 0)
{
ERR_MSG("setsockopt");
return -1;
}
//bind 非必须绑定
//如果不绑定那么系统将由操作系统自动绑定IP和端口
//填充接收方的地址信息结构体,给sendto函数使用
struct sockaddr_in sin;
sin.sin_family = AF_INET; //必须填写AF_INET
sin.sin_port = htnos(PORT); //端口号的网络字节序
sin.sin_addr.s_addr = inet_addr(IP);//广播IP字节序
//如果不想给服务器传参数的话就可以填写这个,sendto最后两个参数
struct sockaddr_in cin;
socklen_t addrlen = sizeof(cin);
while(1)
{
bzero(buf, sizeof(buf));
printf("请输入>>");
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf)-1] = 0;
if(sendto(sfd, buf, sizeof(buf), 0, (struct addrlen *)&cin, sizeof(cin))) < 0)
{
ERR_MSG("sendto");
return -1;
}
printf("发送成功\n");
}
//关闭文件描述符
close(sfd);
return 0;
}
组播的搭建
组播的服务器
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ERR_MSG(msg) \
do \
{ \
fprintf(stderr, "line:%d", __LINE__); \
perror(msg); \
} while (0)
#define IP "192.168.0.156" // 本机IP
#define GRP_IP "224.1.5.6" // 组播IP(224.0.0.0 ~ 239.255.255.255)
#define PORT 1562 // 自定义端口号1023~49151
char buf[128] = ""; // 接收组播客户端发来的消息
int main(int argc, const char *argv[])
{
// 创建套接字
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sfd < 0)
{
ERR_MSG("socket");
return -1;
}
printf("socket success __%d__\n", __LINE__);
// 加入组播
struct ip_mreqn mq;
mq.imr_multiaddr.s_addr = inet_addr(GRP_IP); // 组网IP的网络字节序
mq.imr_address.s_addr = inet_addr(IP); // 本机IP的网络字节序
mq.imr_ifindex = 2; // 设备索引号,网卡编号,用ip ad可以查看
if (setsockopt(sfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mq, sizeof(mq)) < 0)
{
ERR_MSG("setsockpopt");
return -1;
}
printf("setsockoopt success __%d__\n", __LINE__);
// 填写接收方的消息
struct sockaddr_in sin;
sin.sin_family = AF_INET; // 必须填写AF_INET
sin.sin_port = htons(PORT); // 端口号的网络字节序
sin.sin_addr.s_addr = inet_addr(GRP_IP); // 组播IP地址,与加入的组播IP一样
// 绑定bind
if (bind(sfd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
ERR_MSG("bind");
return -1;
}
// 存储数据包是从谁那里发过来的,给recvfrom函数使用
struct sockaddr_in cin;
socklen_t addrlen = sizeof(cin);
ssize_t res = 0;
while (1)
{
bzero(buf, sizeof(buf));
// 接收
res = recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr *)&cin, &addrlen);
if (res < 0)
{
ERR_MSG("recvfrom");
return -1;
}
printf("[%s:%d]:%s", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);
}
//关闭
close(sfd);
return 0;
}
组播的客户端
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ERR_MSG(msg) \
do \
{ \
fprintf(stderr, "line:%d", __LINE__); \
perror(msg); \
} while (0)
#define GRP_IP "224.1.2.3" // 组网IP(224.0.0.0~239.255.255.255)
#define PORT 6666
char buf[128] = ""; // 用来存客户端发送的信息
int main(int argc, const char *argv[])
{
// 创建套接字
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sfd < 0)
{
ERR_MSG("sfd");
return -1;
}
printf("socket success\n");
// bind 非必须绑定
// 填充接收方的地址信息结构体,给sendto函数使用,指定发给谁
struct sockaddr_in sin;
sin.sin_family = AF_INET; // 必须填写AF_INET
sin.sin_port = htons(PORT); // 端口号1023~49151 要转为网络字节序
sin.sin_addr.s_addr = inet_addr(GRP_IP); // 本机IP地址 要转为网络字节序
while(1)
{
bzero(buf, sizeof(buf));
//发送
printf("请输入>>");
fgets(buf, sizeof(buf), stdin);
if(sendto(sfd, buf,sizeof(buf), 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
ERR_MSG("sendto");
return -1;
}
printf("发送成功\n");
}
//关闭
close(sfd);
return 0;
}