用户工具

站点工具


paste

这是本文档旧的修订版!


Copy and Paste

This page is used for copy and paste sharing.

IPv6 Multicast

组播与单播的区别(从应用层角度看):

  • 发送方发送的目的地址不是接收方的IP地址,而是某link,link上某组播地址的一个组,发送数据。
  • 接收方Bind的不是接口的地址+端口概念,而是Bind接口+端口,并从这个接口加入某组播地址的group。接收方在接收组播消息的接口上的本地地址,在应用层看来是无关紧要的。

综上,组播调用时有以下不同:

  • 发送socket,发送前需要额外指定发送组播消息的端口,之后将组播地址与端口正常填入sockaddr_in6
  • 接收socket,接收前常规bind,但只有加入ipv6_mreq指定的组后才会收到该组播地址的消息。ipv6_mreq中指定了一个组播地址与其所在的interface。

但,自己发送组播消息,自己接收时需要额外两步支持Loop:

  • IPV6_MULTICAST_HOPS, 指定最大hops
  • IPV6_MULTICAST_LOOP, 开启LOOP支持

Tips,使用'ip link'查看接口的ifindex。

样例代码

//send
m_udpSocketSend.UseIpv6Mode(1);
m_udpSocketSend.Create();
m_udpSocketSend.SetBlocking(0);
 
//像常规地址一样将组播地址与端口填入目的sockaddr_in6
m_udpSocketSend.SetDestIpAndPort(m_Settings.GetSendRemoteMaddrV6Str(),m_Settings.GetSendRemotePortV6());
 
//指定目的组播地址所在的interface
int ifindex = m_Settings.GetIfIndex();
if (setsockopt(m_udpSocketSend.m_sock_fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
                &ifindex, sizeof(ifindex)) < 0)
{
    return ERROR;
}
 
#if SVW_MULTICAST_SUPPORT_LOOP
int hops = 255;
if(setsockopt(m_udpSocketSend.m_sock_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, sizeof(hops)) < 0)
{
    LOGI("set send Socket IPV6_MULTICAST_HOPS failed.");
    perror("setsockopt");
}
if(setsockopt(m_udpSocketSend.m_sock_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &on, sizeof(on)) < 0)
{
    LOGI("set send Socket IPV6_MULTICAST_LOOP failed.");
    perror("setsockopt");
}
#endif
 
//发送!!
m_udpSocketSend.SendMsg(&sendbuff);
//receive
m_udpSocketReceive.UseIpv6Mode(1);
m_udpSocketReceive.Create();
m_udpSocketReceive.SetBlocking(0);
if(!m_udpSocketReceive.Bind(m_Settings.GetReceivePortV6()))
{
    return ERROR;
}
 
//join multicast group
struct ipv6_mreq mGroupAddr;
crt_memset(&mGroupAddr,0,sizeof(mGroupAddr));
if(!crt_inet_addr_v6(m_Settings.GetReceiveMaddrV6Str(),&mGroupAddr.ipv6mr_multiaddr))
{
    LOGI("invalidate v6 ip %s\n", m_Settings.GetReceiveMaddrV6Str());
    return ERROR;
}
if(m_Settings.GetIfIndex() != 0)
{
    mGroupAddr.ipv6mr_interface = m_Settings.GetIfIndex();
}
if (setsockopt(m_udpSocketReceive.m_sock_fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
                &mGroupAddr, sizeof(mGroupAddr)) < 0)
{
    LOGE("setting join MULTICAST group %s failed.",m_Settings.GetReceiveMaddrV6Str());
    return ERROR;
}

rsync

#rsync推荐样例:
rsync -avIPhz  \
  --exclude='update-backups/*'  \
  --backup-dir=update-backups/`date '+%Y%m%d-%H%m'`/  \
  ~/cv-release/ root@remote.site:/path/to/release/
 
cat >help.txt<<EOF
同步文件夹时,不要省略文件夹的斜杠!虽然远端的代表文件夹的斜杠可以省略。
 
--backup-dir参数让任何被删除或覆盖的文件都移入指定文件夹,这个目录是远端同步目录的相对路径
在本例中是: root@remote.site:/path/to/release/update-backups/20231016-1654/
如果没有删除或覆盖的文件,则不创建该目录
 
--exclude保证本机指定目录不会同步到远端。这个目录是本机同步目录的相对路径
在本例中是: ~/cv-release/update-backups/*
 
注意,不要添加--delete!就不会删除远端任何文件,覆盖的除外。
 
-a: 类似cp中的-a, 等效于-rlptgoD,
    分别是,递归、复制软链接、保持权限、同步修改时间、保持group一致、保持owner一致、保持设备文件一致
    如果,目标文件存在且无权chmod,-p(保持权限)可能权限不足;
    如果,目标rsync非root,-goD可能会忽略,可以考虑用-rlt替代
    在不指定-p保持权限时,覆盖文件会保持远端文件原权限不变,新建文件会遵从本机源文件
-v: verbose
-I: --ignore-times
    忽略时间与大小,一定进行哈希对比
-P: same as --partial --progress
    断点续传大文件
-h: --human-readable
-z: --compress
    先压缩再传输
EOF

Ignore me

paste.1697783137.txt.gz · 最后更改: root