- 步骤
- 声明socket
- 允许reuse socket
- 支持设置TTL
- 设置本机地址
- 向内核申请加入一个组
- [到此可以发数据等]
```c++
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include
#include
using namespace std;
// 端口
int port = 12345;
// ttl
int ttl = 60;
// group
std::string group = "224.0.0.37";
// test str to be sent
std::string message = "hello world";
int main(int argc, char const *argv[])
{
cout << "创建并加入组播组:group:" << group << ", port: " << port << ", TTL:" << ttl << endl;
int udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
if (udp_socket < 0)
{
perror("socket initilize failed");
return 1;
}
// 允许reuse socket port
u_int yes = 1;
if (
setsockopt(
udp_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)) < 0)
{
perror("reuse addr failed");
return 1;
}
// 设置TTL
if (setsockopt(udp_socket, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) < 0)
{
perror("setsockopt ip_ttl failed");
return 1;
}
// 设置本机地址
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port);
// bind socket
if (bind(udp_socket, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
perror("bind socket error");
return 1;
}
// 设置ip
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(group.c_str());
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(udp_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
{
perror("set mutliaddr failed");
return 1;
}
cout << "发送UDP组播,内容:" << message <<endl;
// 创建完成
int nbytes = sendto(udp_socket, message.c_str(), message.size(), 0, (struct sockaddr *)&addr, sizeof(addr));
if (nbytes < 0)
{
perror("send message failed");
}
else
{
cout << "发送成功";
}
return 0;
```