1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
#include "StarUdp.hpp"
#include "StarLogging.hpp"
#include "StarNetImpl.hpp"
namespace Star {
UdpSocket::UdpSocket(NetworkMode networkMode) : Socket(SocketType::Udp, networkMode) {}
size_t UdpSocket::receive(HostAddressWithPort* address, char* data, size_t datasize) {
ReadLocker locker(m_mutex);
checkOpen("UdpSocket::receive");
int flags = 0;
int len;
struct sockaddr_storage sockAddr;
socklen_t sockAddrLen = sizeof(sockAddr);
len = ::recvfrom(m_impl->socketDesc, data, datasize, flags, (struct sockaddr*)&sockAddr, &sockAddrLen);
if (len < 0) {
if (!isActive())
throw SocketClosedException("Connection closed");
else if (netErrorInterrupt())
len = 0;
else
throw NetworkException(strf("udp recv error: {}", netErrorString()));
}
if (address)
setAddressFromNative(*address, m_localAddress.address().mode(), &sockAddr);
return len;
}
size_t UdpSocket::send(HostAddressWithPort const& address, char const* data, size_t size) {
ReadLocker locker(m_mutex);
checkOpen("UdpSocket::send");
struct sockaddr_storage sockAddr;
socklen_t sockAddrLen;
setNativeFromAddress(address, &sockAddr, &sockAddrLen);
int len = ::sendto(m_impl->socketDesc, data, size, 0, (struct sockaddr*)&sockAddr, sockAddrLen);
if (len < 0) {
if (!isActive())
throw SocketClosedException("Connection closed");
else if (netErrorInterrupt())
len = 0;
else
throw NetworkException(strf("udp send error: {}", netErrorString()));
}
return len;
}
UdpServer::UdpServer(HostAddressWithPort const& address)
: m_hostAddress(address), m_listenSocket(make_shared<UdpSocket>(m_hostAddress.address().mode())) {
m_listenSocket->setNonBlocking(true);
m_listenSocket->bind(m_hostAddress);
Logger::debug("UdpServer listening on: {}", m_hostAddress);
}
UdpServer::~UdpServer() {
close();
}
size_t UdpServer::receive(HostAddressWithPort* address, char* data, size_t bufsize, unsigned timeout) {
Socket::poll({{m_listenSocket, {true, false}}}, timeout);
return m_listenSocket->receive(address, data, bufsize);
}
size_t UdpServer::send(HostAddressWithPort const& address, char const* data, size_t len) {
return m_listenSocket->send(address, data, len);
}
void UdpServer::close() {
m_listenSocket->close();
}
bool UdpServer::isListening() const {
return m_listenSocket->isActive();
}
}
|