BlinkenArea - GitList
Repositories
Blog
Wiki
Blinker
Code
Commits
Branches
Tags
Search
Tree:
1418bf1
Branches
Tags
master
Blinker
src
windows
Udp6Sock.cpp
UDP sockets for Windows
Stefan Schuermans
commited
1418bf1
at 2017-10-28 20:24:17
Udp6Sock.cpp
Blame
History
Raw
/* Blinker Copyright 2011-2014 Stefan Schuermans <stefan@blinkenarea.org> Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html a blinkenarea.org project */ #include <winsock2.h> #include <string> #include "Io.h" #include "Udp6Addr.h" #include "Udp6Sock.h" namespace Blinker { /// constructor Udp6Sock::Udp6Sock() { // create socket m_socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (m_socket == INVALID_SOCKET) return; // switch to nonblocking mode u_long nonblock = 1; if (ioctlsocket(m_socket, FIONBIO, &nonblock) != 0) { closesocket(m_socket); m_socket = INVALID_SOCKET; return; } // enable address re-use BOOL opt = TRUE; if (setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) != 0) { closesocket(m_socket); m_socket = INVALID_SOCKET; return; } } /// destructor Udp6Sock::~Udp6Sock() { // exit if not initialized if (m_socket == INVALID_SOCKET) return; // shutdown and close socket shutdown(m_socket, SD_BOTH); closesocket(m_socket); m_socket = INVALID_SOCKET; } /** * @brief get address the socket is bound to * @param[out] addr local addess the socket is bound to * @return if local address could be obtained */ bool Udp6Sock::getAddr(Udp6Addr &addr) { struct sockaddr * sockaddr; int socklen; // exit with error if not initialized if (m_socket == INVALID_SOCKET) return false; // get local name of socket sockaddr = (struct sockaddr *)&addr.m_addr; socklen = sizeof(addr.m_addr); if (getsockname(m_socket, sockaddr, &socklen) != 0) return false; return socklen <= (int)sizeof(addr.m_addr); // check if not truncated } /** * @brief bind socket * @param[in] addr local address to bind to * @return if binding succeeded */ bool Udp6Sock::bind(const Udp6Addr &addr) { const struct sockaddr * sockaddr; int socklen; // exit with error if not initialized if (m_socket == INVALID_SOCKET) return false; // bind sockaddr = (const struct sockaddr *)&addr.m_addr; socklen = sizeof(addr.m_addr); return ::bind(m_socket, sockaddr, socklen) == 0; } /** * @brief send to socket * @param[in] data data to send in message * @param[in] addr address the message should be sent to * @return if the message could be sent */ bool Udp6Sock::send(const std::string &data, const Udp6Addr &addr) { const struct sockaddr * sockaddr; int socklen; ssize_t len; // exit with error if not initialized if (m_socket == INVALID_SOCKET) return false; // send message sockaddr = (const struct sockaddr *)&addr.m_addr; socklen = sizeof(addr.m_addr); len = sendto(m_socket, data.c_str(), data.size(), 0, sockaddr, socklen); return len == (ssize_t)data.size(); } /** * @brief receive from socket * @param[out] data data in received message * @param[out] addr address the message has been received from * @return if a message has been received */ bool Udp6Sock::recv(std::string &data, Udp6Addr &addr) { char buf[65536]; struct sockaddr * sockaddr; int socklen; ssize_t len; // exit with error if not initialized if (m_socket == INVALID_SOCKET) return false; // receive message sockaddr = (struct sockaddr *)&addr.m_addr; socklen = sizeof(addr.m_addr); len = recvfrom(m_socket, buf, sizeof(buf), 0, sockaddr, &socklen); if (len < 0 || socklen > (int)sizeof(addr.m_addr)) // error or truncated return false; data.assign(buf, len); return true; } } // namespace Blinker