#ifndef __JNET__JUDPSOCKET__ #define __JNET__JUDPSOCKET__ #include "JLang/JException.hh" #include "JSystem/JNetwork.hh" #include "JNet/JSocket.hh" #include "JNet/JHostname.hh" /** * \author cpellegrino, mdejong */ namespace JNET {} namespace JPP { using namespace JNET; } namespace JNET { using JLANG::JSocketException; /** * UDP socket. */ class JUDPSocket : public JSocket { public: using JSocket::read; /** * Default constructor. */ JUDPSocket() : JSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) {} /** * Constructor. * UDP socket for client. * * \param hostname host name of destination */ JUDPSocket(const JHostname& hostname): JSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) { this->setReuseAddress(true); this->setIPnumber(JSYSTEM::getIPnumber(hostname.hostname)); this->setPort(hostname.port); } /** * Constructor. * UDP socket for server. * * \param port port number of receiver */ JUDPSocket(const int port): JSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) { this->setReuseAddress(true); this->setIPnumber(); this->setPort(port); if (::bind(getFileDescriptor(), getSockaddr(), sizeof(sockaddr)) < 0) { THROW(JSocketException, "Bind socket failed at port " << port); } } /** * Read data from socket. * * \param buffer buffer * \param length number of bytes to read * \return number of bytes actually read */ int read(char* buffer, const int length) override { // read also zero-length datagram, as opposed to method read. return ::recv(this->getFileDescriptor(), buffer, length, 0); } /** * Read data from socket. * * \param buffer buffer * \param length number of bytes to read * \param udp UDP socket * \return number of bytes actually read */ int read(char* buffer, const int length, JUDPSocket& udp) { socklen_t size = sizeof(sockaddr); udp.setFileDescriptor(this->getFileDescriptor()); return ::recvfrom(this->getFileDescriptor(), buffer, length, 0, udp.getSockaddr(), &size); } /** * Write data to socket. * * \param buffer buffer * \param length number of bytes to write * \return number of bytes actually written */ virtual int write(const char* buffer, const int length) override { return ::sendto(this->getFileDescriptor(), buffer, length, 0, this->getSockaddr(), sizeof(sockaddr)); } }; } #endif