BlinkenArea - GitList
Repositories
Blog
Wiki
Blinker
Code
Commits
Branches
Tags
Search
Tree:
b6b2996
Branches
Tags
master
Blinker
src
linux
Udp4Sock.cpp
update copyright years
Stefan Schuermans
commited
b6b2996
at 2014-01-02 21:57:13
Udp4Sock.cpp
Blame
History
Raw
/* Blinker Copyright 2011-2014Stefan Schuermans <stefan@blinkenarea.org> Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html a blinkenarea.org project */ #include <fcntl.h> #include <netinet/in.h> #include <string> #include <sys/socket.h> #include <sys/types.h> #include <unistd.h> #include "Io.h" #include "Udp4Addr.h" #include "Udp4Sock.h" namespace Blinker { /// constructor Udp4Sock::Udp4Sock() { int flags, opt; // create socket m_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (m_fd == -1) return; // switch to nonblocking mode flags = fcntl(m_fd, F_GETFL); if (flags == -1 || fcntl(m_fd, F_SETFL, flags | O_NONBLOCK) != 0) { close(m_fd); m_fd = -1; return; } // enable address re-use opt = 1; if (setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) != 0) { close(m_fd); m_fd = -1; return; } } /// destructor Udp4Sock::~Udp4Sock() { // exit if not initialized if (m_fd == -1) return; // shutdown and close socket shutdown(m_fd, SHUT_RDWR); close(m_fd); m_fd = -1; } /** * @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 Udp4Sock::getAddr(Udp4Addr &addr) { struct sockaddr * sockaddr; socklen_t socklen; // exit with error if not initialized if (m_fd == -1) return false; // get local name of socket sockaddr = (struct sockaddr *)&addr.m_addr; socklen = sizeof(addr.m_addr); if (getsockname(m_fd, sockaddr, &socklen) != 0) return false; return socklen <= sizeof(addr.m_addr); // check if not truncated } /** * @brief bind socket * @param[in] addr local address to bind to * @return if binding succeeded */ bool Udp4Sock::bind(const Udp4Addr &addr) { const struct sockaddr * sockaddr; socklen_t socklen; // exit with error if not initialized if (m_fd == -1) return false; // bind sockaddr = (const struct sockaddr *)&addr.m_addr; socklen = sizeof(addr.m_addr); return ::bind(m_fd, 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 Udp4Sock::send(const std::string &data, const Udp4Addr &addr) { const struct sockaddr * sockaddr; socklen_t socklen; ssize_t len; // exit with error if not initialized if (m_fd == -1) return false; // send message sockaddr = (const struct sockaddr *)&addr.m_addr; socklen = sizeof(addr.m_addr); len = sendto(m_fd, 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 Udp4Sock::recv(std::string &data, Udp4Addr &addr) { char buf[65536]; struct sockaddr * sockaddr; socklen_t socklen; ssize_t len; // exit with error if not initialized if (m_fd == -1) return false; // receive message sockaddr = (struct sockaddr *)&addr.m_addr; socklen = sizeof(addr.m_addr); len = recvfrom(m_fd, buf, sizeof(buf), 0, sockaddr, &socklen); if (len < 0 || socklen > sizeof(addr.m_addr)) // error or address truncated return false; data.assign(buf, len); return true; } } // namespace Blinker