sources/network/udpsocket.cpp

changeset 189
248d0b85cbda
parent 186
9330b93d9946
child 190
90bf9049e5eb
equal deleted inserted replaced
188:5fc32e4b2a8c 189:248d0b85cbda
45 #include <fcntl.h> 45 #include <fcntl.h>
46 #include "../huffman/huffman.h" 46 #include "../huffman/huffman.h"
47 47
48 BEGIN_ZFC_NAMESPACE 48 BEGIN_ZFC_NAMESPACE
49 49
50 char UDPSocket::HuffmanBuffer[131072]; 50 static char HuffmanBuffer[131072];
51 51
52 // ----------------------------------------------------------------------------- 52 net::UDPSocket::UDPSocket() :
53 // 53 file_descriptor{::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)} {}
54 UDPSocket::UDPSocket() :
55 m_socket (socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) {}
56 54
57 // ----------------------------------------------------------------------------- 55 net::UDPSocket::~UDPSocket()
58 //
59 UDPSocket::~UDPSocket()
60 { 56 {
61 #ifdef _WIN32 57 #ifdef _WIN32
62 closesocket (m_socket); 58 ::closesocket(m_socket);
63 #else 59 #else
64 close (m_socket); 60 ::close(this->file_descriptor);
65 #endif 61 #endif
66 } 62 }
67 63
68 // ------------------------------------------------------------------------------------------------- 64 bool net::UDPSocket::set_blocking(bool a, std::ostream& errors)
69 //
70 bool UDPSocket::set_blocking (bool a)
71 { 65 {
72 #ifndef _WIN32 66 #ifndef _WIN32
73 int flags = fcntl (m_socket, F_GETFL, 0); 67 int flags = ::fcntl(this->file_descriptor, F_GETFL, 0);
74 int newflags = a ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK); 68 int newflags = a ?(flags & ~O_NONBLOCK) :(flags | O_NONBLOCK);
75 69 if (flags < 0 || ::fcntl(this->file_descriptor, F_SETFL, newflags) != 0)
76 if (flags < 0 || fcntl (m_socket, F_SETFL, newflags) != 0)
77 { 70 {
78 m_error = "Unable to set socket as non-blocking"; 71 errors << "Unable to set the UDP socket as non-blocking";
79 return false; 72 return false;
80 } 73 }
81 74 else
82 return true; 75 {
76 return true;
77 }
83 #else 78 #else
84 unsigned long mode = a ? 0 : 1; 79 unsigned long mode = a ? 0 : 1;
85 80
86 if (ioctlsocket (m_socket, FIONBIO, &mode) != 0) 81 if (::ioctlsocket(m_socket, FIONBIO, &mode) != 0)
87 { 82 {
88 m_error = strerror (errno); 83 errors << strerror(errno);
89 return false; 84 return false;
90 } 85 }
91 86 else
92 return true; 87 {
88 return true;
89 }
93 #endif 90 #endif
94 } 91 }
95 92
96 // ------------------------------------------------------------------------------------------------- 93 bool net::UDPSocket::bind(const net::port_t port, std::ostream& errors)
97 //
98 bool UDPSocket::bind (unsigned short port)
99 { 94 {
100 sockaddr_in svaddr; 95 sockaddr_in svaddr;
101 memset (&svaddr, 0, sizeof svaddr); 96 std::memset(&svaddr, 0, sizeof svaddr);
102 svaddr.sin_family = AF_INET; 97 svaddr.sin_family = AF_INET;
103 svaddr.sin_port = htons (port); 98 svaddr.sin_port = htons(port);
104 svaddr.sin_addr.s_addr = htonl (INADDR_ANY); 99 svaddr.sin_addr.s_addr = htonl(INADDR_ANY);
105 100 if (::bind(this->file_descriptor, reinterpret_cast<sockaddr*>(&svaddr), sizeof svaddr) == -1)
106 if (::bind (m_socket, reinterpret_cast<sockaddr*> (&svaddr), sizeof svaddr) == -1)
107 { 101 {
108 m_error = "Couldn't bind to port "s + std::to_string(port); 102 errors << "Couldn't bind to port "s + std::to_string(port);
109 return false; 103 return false;
110 } 104 }
111 105 else
112 return true; 106 {
107 return true;
108 }
113 } 109 }
114 110
115 // ------------------------------------------------------------------------------------------------- 111 bool net::UDPSocket::read(Datagram& datagram, std::ostream& errors)
116 //
117 bool UDPSocket::read (Datagram& datagram)
118 { 112 {
119 sockaddr_in claddr; 113 sockaddr_in claddr;
120 socklen_t socklen = sizeof claddr; 114 socklen_t socklen = sizeof claddr;
121 int length = ::recvfrom (m_socket, HuffmanBuffer, sizeof HuffmanBuffer, 0, 115 const int length = ::recvfrom(
122 reinterpret_cast<sockaddr*> (&claddr), &socklen); 116 this->file_descriptor,
123 117 zfc::HuffmanBuffer,
118 sizeof zfc::HuffmanBuffer,
119 0,
120 reinterpret_cast<sockaddr*>(&claddr),
121 &socklen
122 );
124 if (length == -1) 123 if (length == -1)
125 { 124 {
126 if (errno != EWOULDBLOCK) 125 if (errno != EWOULDBLOCK)
127 m_error = std::string ("recvfrom error: ") + strerror (errno); 126 {
128 127 errors << std::string("recvfrom error: ") + std::strerror(errno);
128 }
129 return false; 129 return false;
130 } 130 }
131
132 unsigned char decodedPacket[MAX_DATAGRAM_LENGTH]; 131 unsigned char decodedPacket[MAX_DATAGRAM_LENGTH];
133 int decodedLength = sizeof decodedPacket; 132 int decodedLength = sizeof decodedPacket;
134 HUFFMAN_Decode (reinterpret_cast<unsigned char*> (HuffmanBuffer), 133 ::HUFFMAN_Decode(reinterpret_cast<unsigned char*>(HuffmanBuffer),
135 decodedPacket, length, &decodedLength); 134 decodedPacket, length, &decodedLength);
136 datagram.address.host = ntohl (claddr.sin_addr.s_addr); 135 datagram.address.host = ntohl(claddr.sin_addr.s_addr);
137 datagram.address.port = ntohs (claddr.sin_port); 136 datagram.address.port = ntohs(claddr.sin_port);
138 datagram.message = ByteArray{&decodedPacket[0], &decodedPacket[decodedLength]}; 137 datagram.message = ByteArray{&decodedPacket[0], &decodedPacket[decodedLength]};
139 return true; 138 return true;
140 } 139 }
141 140
142 // ------------------------------------------------------------------------------------------------- 141 bool net::UDPSocket::send(const net::ip_address& address, const ByteArray& data, std::ostream& errors)
143 //
144 bool UDPSocket::send (const net::ip_address& address, const ByteArray& data)
145 { 142 {
146 int encodedlength = sizeof HuffmanBuffer; 143 int encodedlength = sizeof HuffmanBuffer;
147 HUFFMAN_Encode (data.data(), reinterpret_cast<unsigned char*> (HuffmanBuffer), data.size(), &encodedlength); 144 ::HUFFMAN_Encode(data.data(), reinterpret_cast<unsigned char*>(HuffmanBuffer), data.size(), &encodedlength);
148 sockaddr_in claddr = net::ip_address_to_sockaddr_in(address); 145 sockaddr_in claddr = net::ip_address_to_sockaddr_in(address);
149 int res = ::sendto (m_socket, HuffmanBuffer, encodedlength, 0, 146 const int send_result = ::sendto(
150 reinterpret_cast<sockaddr*> (&claddr), sizeof claddr); 147 this->file_descriptor,
151 148 HuffmanBuffer,
152 if (res == -1) 149 encodedlength,
150 0,
151 reinterpret_cast<sockaddr*>(&claddr),
152 sizeof claddr
153 );
154 if (send_result == -1)
153 { 155 {
154 m_error = std::string ("Unable to launch packet: ") + strerror (errno); 156 errors << "Unable to launch packet: "s + std::strerror(errno);
155 return false; 157 return false;
156 } 158 }
157 159 else
158 return true; 160 {
161 return true;
162 }
159 } 163 }
160 164
161 END_ZFC_NAMESPACE 165 END_ZFC_NAMESPACE

mercurial