📄 udpsocket.cpp.svn-base
字号:
void UdpSocket::OnRead()
{
#ifdef ENABLE_IPV6
#ifdef IPPROTO_IPV6
if (IsIpv6())
{
struct sockaddr_in6 sa;
socklen_t sa_len = sizeof(sa);
if (m_b_read_ts)
{
struct timeval ts;
Utility::GetTime(&ts);
#if !defined(LINUX) && !defined(MACOSX)
int n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len);
#else
int n = ReadTS(m_ibuf, m_ibufsz, (struct sockaddr *)&sa, sa_len, &ts);
#endif
if (n > 0)
{
this -> OnRawData(m_ibuf, n, (struct sockaddr *)&sa, sa_len, &ts);
}
else
if (n == -1)
{
#ifdef _WIN32
if (Errno != WSAEWOULDBLOCK)
#else
if (Errno != EWOULDBLOCK)
#endif
Handler().LogError(this, "recvfrom", Errno, StrError(Errno), LOG_LEVEL_ERROR);
}
return;
}
int n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len);
int q = m_retries; // receive max 10 at one cycle
while (n > 0)
{
if (sa_len != sizeof(sa))
{
Handler().LogError(this, "recvfrom", 0, "unexpected address struct size", LOG_LEVEL_WARNING);
}
this -> OnRawData(m_ibuf, n, (struct sockaddr *)&sa, sa_len);
if (!q--)
break;
//
n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len);
}
if (n == -1)
{
#ifdef _WIN32
if (Errno != WSAEWOULDBLOCK)
#else
if (Errno != EWOULDBLOCK)
#endif
Handler().LogError(this, "recvfrom", Errno, StrError(Errno), LOG_LEVEL_ERROR);
}
return;
}
#endif
#endif
struct sockaddr_in sa;
socklen_t sa_len = sizeof(sa);
if (m_b_read_ts)
{
struct timeval ts;
Utility::GetTime(&ts);
#if !defined(LINUX) && !defined(MACOSX)
int n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len);
#else
int n = ReadTS(m_ibuf, m_ibufsz, (struct sockaddr *)&sa, sa_len, &ts);
#endif
if (n > 0)
{
this -> OnRawData(m_ibuf, n, (struct sockaddr *)&sa, sa_len, &ts);
}
else
if (n == -1)
{
#ifdef _WIN32
if (Errno != WSAEWOULDBLOCK)
#else
if (Errno != EWOULDBLOCK)
#endif
Handler().LogError(this, "recvfrom", Errno, StrError(Errno), LOG_LEVEL_ERROR);
}
return;
}
int n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len);
int q = m_retries;
while (n > 0)
{
if (sa_len != sizeof(sa))
{
Handler().LogError(this, "recvfrom", 0, "unexpected address struct size", LOG_LEVEL_WARNING);
}
this -> OnRawData(m_ibuf, n, (struct sockaddr *)&sa, sa_len);
if (!q--)
break;
//
n = recvfrom(GetSocket(), m_ibuf, m_ibufsz, 0, (struct sockaddr *)&sa, &sa_len);
}
if (n == -1)
{
#ifdef _WIN32
if (Errno != WSAEWOULDBLOCK)
#else
if (Errno != EWOULDBLOCK)
#endif
Handler().LogError(this, "recvfrom", Errno, StrError(Errno), LOG_LEVEL_ERROR);
}
}
void UdpSocket::SetBroadcast(bool b)
{
int one = 1;
int zero = 0;
if (GetSocket() == INVALID_SOCKET)
{
CreateConnection();
}
if (b)
{
if (setsockopt(GetSocket(), SOL_SOCKET, SO_BROADCAST, (char *) &one, sizeof(one)) == -1)
{
Handler().LogError(this, "SetBroadcast", Errno, StrError(Errno), LOG_LEVEL_WARNING);
}
}
else
{
if (setsockopt(GetSocket(), SOL_SOCKET, SO_BROADCAST, (char *) &zero, sizeof(zero)) == -1)
{
Handler().LogError(this, "SetBroadcast", Errno, StrError(Errno), LOG_LEVEL_WARNING);
}
}
}
bool UdpSocket::IsBroadcast()
{
int is_broadcast = 0;
socklen_t size;
if (GetSocket() == INVALID_SOCKET)
{
CreateConnection();
}
if (getsockopt(GetSocket(), SOL_SOCKET, SO_BROADCAST, (char *)&is_broadcast, &size) == -1)
{
Handler().LogError(this, "IsBroadcast", Errno, StrError(Errno), LOG_LEVEL_WARNING);
}
return is_broadcast != 0;
}
void UdpSocket::SetMulticastTTL(int ttl)
{
if (GetSocket() == INVALID_SOCKET)
{
CreateConnection();
}
if (setsockopt(GetSocket(), SOL_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(int)) == -1)
{
Handler().LogError(this, "SetMulticastTTL", Errno, StrError(Errno), LOG_LEVEL_WARNING);
}
}
int UdpSocket::GetMulticastTTL()
{
int ttl = 0;
socklen_t size = sizeof(int);
if (GetSocket() == INVALID_SOCKET)
{
CreateConnection();
}
if (getsockopt(GetSocket(), SOL_IP, IP_MULTICAST_TTL, (char *)&ttl, &size) == -1)
{
Handler().LogError(this, "GetMulticastTTL", Errno, StrError(Errno), LOG_LEVEL_WARNING);
}
return ttl;
}
void UdpSocket::SetMulticastLoop(bool x)
{
if (GetSocket() == INVALID_SOCKET)
{
CreateConnection();
}
#ifdef ENABLE_IPV6
#ifdef IPPROTO_IPV6
if (IsIpv6())
{
int val = x ? 1 : 0;
if (setsockopt(GetSocket(), IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *)&val, sizeof(int)) == -1)
{
Handler().LogError(this, "SetMulticastLoop", Errno, StrError(Errno), LOG_LEVEL_WARNING);
}
return;
}
#endif
#endif
int val = x ? 1 : 0;
if (setsockopt(GetSocket(), SOL_IP, IP_MULTICAST_LOOP, (char *)&val, sizeof(int)) == -1)
{
Handler().LogError(this, "SetMulticastLoop", Errno, StrError(Errno), LOG_LEVEL_WARNING);
}
}
bool UdpSocket::IsMulticastLoop()
{
if (GetSocket() == INVALID_SOCKET)
{
CreateConnection();
}
#ifdef ENABLE_IPV6
#ifdef IPPROTO_IPV6
if (IsIpv6())
{
int is_loop = 0;
socklen_t size = sizeof(int);
if (getsockopt(GetSocket(), IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *)&is_loop, &size) == -1)
{
Handler().LogError(this, "IsMulticastLoop", Errno, StrError(Errno), LOG_LEVEL_WARNING);
}
return is_loop ? true : false;
}
#endif
#endif
int is_loop = 0;
socklen_t size = sizeof(int);
if (getsockopt(GetSocket(), SOL_IP, IP_MULTICAST_LOOP, (char *)&is_loop, &size) == -1)
{
Handler().LogError(this, "IsMulticastLoop", Errno, StrError(Errno), LOG_LEVEL_WARNING);
}
return is_loop ? true : false;
}
void UdpSocket::AddMulticastMembership(const std::string& group, const std::string& local_if, int if_index)
{
if (GetSocket() == INVALID_SOCKET)
{
CreateConnection();
}
#ifdef ENABLE_IPV6
#ifdef IPPROTO_IPV6
if (IsIpv6())
{
struct ipv6_mreq x;
struct in6_addr addr;
if (Utility::u2ip( group, addr ))
{
x.ipv6mr_multiaddr = addr;
x.ipv6mr_interface = if_index;
if (setsockopt(GetSocket(), IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *)&x, sizeof(struct ipv6_mreq)) == -1)
{
Handler().LogError(this, "AddMulticastMembership", Errno, StrError(Errno), LOG_LEVEL_WARNING);
}
}
return;
}
#endif
#endif
struct ip_mreq x; // ip_mreqn
ipaddr_t addr;
if (Utility::u2ip( group, addr ))
{
memcpy(&x.imr_multiaddr.s_addr, &addr, sizeof(addr));
Utility::u2ip( local_if, addr);
memcpy(&x.imr_interface.s_addr, &addr, sizeof(addr));
// x.imr_ifindex = if_index;
if (setsockopt(GetSocket(), SOL_IP, IP_ADD_MEMBERSHIP, (char *)&x, sizeof(struct ip_mreq)) == -1)
{
Handler().LogError(this, "AddMulticastMembership", Errno, StrError(Errno), LOG_LEVEL_WARNING);
}
}
}
void UdpSocket::DropMulticastMembership(const std::string& group, const std::string& local_if, int if_index)
{
if (GetSocket() == INVALID_SOCKET)
{
CreateConnection();
}
#ifdef ENABLE_IPV6
#ifdef IPPROTO_IPV6
if (IsIpv6())
{
struct ipv6_mreq x;
struct in6_addr addr;
if (Utility::u2ip( group, addr ))
{
x.ipv6mr_multiaddr = addr;
x.ipv6mr_interface = if_index;
if (setsockopt(GetSocket(), IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, (char *)&x, sizeof(struct ipv6_mreq)) == -1)
{
Handler().LogError(this, "DropMulticastMembership", Errno, StrError(Errno), LOG_LEVEL_WARNING);
}
}
return;
}
#endif
#endif
struct ip_mreq x; // ip_mreqn
ipaddr_t addr;
if (Utility::u2ip( group, addr ))
{
memcpy(&x.imr_multiaddr.s_addr, &addr, sizeof(addr));
Utility::u2ip( local_if, addr);
memcpy(&x.imr_interface.s_addr, &addr, sizeof(addr));
// x.imr_ifindex = if_index;
if (setsockopt(GetSocket(), SOL_IP, IP_DROP_MEMBERSHIP, (char *)&x, sizeof(struct ip_mreq)) == -1)
{
Handler().LogError(this, "DropMulticastMembership", Errno, StrError(Errno), LOG_LEVEL_WARNING);
}
}
}
#ifdef ENABLE_IPV6
#ifdef IPPROTO_IPV6
void UdpSocket::SetMulticastHops(int hops)
{
if (GetSocket() == INVALID_SOCKET)
{
CreateConnection();
}
if (!IsIpv6())
{
Handler().LogError(this, "SetMulticastHops", 0, "Ipv6 only", LOG_LEVEL_ERROR);
return;
}
if (setsockopt(GetSocket(), IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&hops, sizeof(int)) == -1)
{
Handler().LogError(this, "SetMulticastHops", Errno, StrError(Errno), LOG_LEVEL_WARNING);
}
}
int UdpSocket::GetMulticastHops()
{
if (GetSocket() == INVALID_SOCKET)
{
CreateConnection();
}
if (!IsIpv6())
{
Handler().LogError(this, "SetMulticastHops", 0, "Ipv6 only", LOG_LEVEL_ERROR);
return -1;
}
int hops = 0;
socklen_t size = sizeof(int);
if (getsockopt(GetSocket(), IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&hops, &size) == -1)
{
Handler().LogError(this, "GetMulticastHops", Errno, StrError(Errno), LOG_LEVEL_WARNING);
}
return hops;
}
#endif // IPPROTO_IPV6
#endif
bool UdpSocket::IsBound()
{
return m_bind_ok;
}
void UdpSocket::OnRawData(const char *buf, size_t len, struct sockaddr *sa, socklen_t sa_len)
{
}
void UdpSocket::OnRawData(const char *buf, size_t len, struct sockaddr *sa, socklen_t sa_len, struct timeval *ts)
{
}
port_t UdpSocket::GetPort()
{
return m_port;
}
int UdpSocket::GetLastSizeWritten()
{
return m_last_size_written;
}
void UdpSocket::SetTimestamp(bool x)
{
m_b_read_ts = x;
}
#ifdef SOCKETS_NAMESPACE
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -