Newer
Older
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include "udpsocket.hpp"
#include <stdexcept>
#include <unistd.h>
#include <sys/socket.h>
UdpSocket::UdpSocket(SockAddr _local)
: local{_local}, sockfd{0}
{
if (local.address.type == IpAddr::Type::V4)
{
raw_socklen = sizeof(sockaddr_in);
address_family = AF_INET;
}
else if (local.address.type == IpAddr::Type::V6)
{
raw_socklen = sizeof(sockaddr_in6);
address_family = AF_INET6;
}
else
{
throw std::runtime_error("Cant create UdpSocket from IpAddr::Type::Undef");
}
}
UdpSocket::UdpSocket(IpAddr localAddress, uint16_t port)
: UdpSocket{SockAddr{localAddress, port}}
{ }
UdpSocket::UdpSocket(const std::string &localAddress, uint16_t port)
: UdpSocket{SockAddr{localAddress, port}}
{ }
UdpSocket::UdpSocket(const std::string &localAddressPort)
: UdpSocket{SockAddr{localAddressPort}}
{ }
UdpSocket::~UdpSocket()
{
close();
}
void UdpSocket::bind()
{
if (sockfd > 0)
throw std::runtime_error("Can't call bind on open socket");
sockfd = socket(address_family, SOCK_DGRAM, 0);
if (sockfd <= 0)
{
throw std::runtime_error("Creating UDP Socket failed");
}
if (::bind(sockfd, &local.raw_sockaddr.generic, raw_socklen) != 0)
{
close();
throw std::runtime_error("Binding UDP Socket failed");
}
}
ssize_t UdpSocket::sendTo(const SockAddr &remote, const void *data, size_t len)
{
if (remote.address.type != local.address.type)
{
throw std::runtime_error("Can only send to remote addresses with the same ip type");
}
// TODO: Lookup flags
ssize_t bytes_sent = ::sendto(sockfd, data, len, 0, &remote.raw_sockaddr.generic, raw_socklen);
if (bytes_sent < 0)
{
throw std::runtime_error("Error while writing to socket");
}
return bytes_sent;
}
ssize_t UdpSocket::sendTo(const std::string &remoteAddr, uint16_t port, const void *data, size_t len)
{
return sendTo(SockAddr(remoteAddr, port), data, len);
}
ssize_t UdpSocket::sendTo(const std::string &remoteAddrPort, const void *data, size_t len)
{
return sendTo(SockAddr(remoteAddrPort), data, len);
}
ssize_t UdpSocket::receive(void *data, size_t len, SockAddr &remote)
{
SockAddr::RawSockAddr remote_raw_saddr = {0};
// TODO: Lookup flags
ssize_t bytes_read = ::recvfrom(sockfd, data, len, 0, &remote_raw_saddr.generic, &raw_socklen);
if (bytes_read < 0)
{
throw std::runtime_error("Error while reading from socket");
}
remote = SockAddr(&remote_raw_saddr.generic, local.address.type);
return bytes_read;
}
ssize_t UdpSocket::receive(void *data, size_t len)
{
SockAddr::RawSockAddr remote_raw_saddr = {0};
// TODO: Lookup flags
ssize_t bytes_read = ::recvfrom(sockfd, data, len, 0, &remote_raw_saddr.generic, &raw_socklen);
if (bytes_read < 0)
{
throw std::runtime_error("Error while reading from socket");
}
return bytes_read;
}
void UdpSocket::close()
{
if (sockfd != 0)
{
::close(sockfd);
}
sockfd = 0;
}