Skip to content
Snippets Groups Projects
udpsocket.hpp 7.81 KiB
Newer Older
  • Learn to ignore specific revisions
  • Daniel Müller's avatar
    Daniel Müller committed
    #ifndef _UDPSOCKET_HPP
    #define _UDPSOCKET_HPP
    
    #include "sockaddr.hpp"
    
    
    namespace netlib
    {
    
    
    
    Daniel Müller's avatar
    Daniel Müller committed
    /**
     * @brief The UdpSocket can be used to receive UDP packets from and send UDP
     * packets to any target address.
     */
    class UdpSocket
    {
    private:
        /**
         * @brief The local SockAddr that is used to bind to and listen.
         */
        SockAddr local;
    
        /**
         * @brief The filedescriptor of the current socket. If this is 0, the socket
         * is closed (unbound).
         */
        int sockfd;
    
        /**
         * @brief The length in bytes of the raw sockaddr for either sockaddr_in 
         * (Ipv4) or sockaddr_in6 (Ipv6) depending on what address type is in use.
         */
        socklen_t raw_socklen;
    
        /**
         * @brief The address family (address type) should either be AF_INET for 
         * Ipv4 or AF_INET6 for Ipv6.
         */
        int address_family;
    
    
        /**
         * @brief If set to true, the socket is automatically closed on destruction
         */
    
        bool autoclose = true;
    
    Daniel Müller's avatar
    Daniel Müller committed
    public:
    
    
        /**
         * @brief Create a UdpSocket that will be bound to Ipv4 0.0.0.0 and the 
         * port 0. This will use a random free port and is useful for sending 
         * only.
         */
        UdpSocket();
    
    
    Daniel Müller's avatar
    Daniel Müller committed
        /**
         * @brief Create a UdpSocket that will be bound to the local address and 
         * port that is specified in the SockAddr. 
         * If the socket is only used to send UDP packets, the "any" address 
         * (0.0.0.0 for Ipv4, ::0 for Ipv6) should be used with the port 0. That 
         * will use a random free port.
         * If the socket is used to receive packets, the right port must be used.
         * 
         * @param local The SockAddr that will be listened to.
         */
        UdpSocket(SockAddr local);
    
        /**
         * @brief Same as UdpSocket(SockAddr) and the parameters are passed to 
         * SockAddr constructor.
         * 
         * @see SockAddr
         */
        UdpSocket(IpAddr localAddress, uint16_t port);
    
        /**
         * @brief Same as UdpSocket(SockAddr) and the parameters are passed to 
         * SockAddr constructor.
         * 
         * @see SockAddr
         */
        UdpSocket(const std::string &localAddress, uint16_t port);
    
        /**
         * @brief Same as UdpSocket(SockAddr) and the parameters are passed to 
         * SockAddr constructor.
         * 
         * @see SockAddr
         */
        UdpSocket(const std::string &localAddressPort);
    
        /**
         * @brief The socket is automatically closed when the UdpSocket is 
         * destroyed.
         */
        ~UdpSocket();
    
    
        UdpSocket(UdpSocket &&other);
    
        UdpSocket& operator=(UdpSocket &&other);
    
    Daniel Müller's avatar
    Daniel Müller committed
    
        /**
    
         * @brief Copying UdpSocket is not allowed. See clone() for explicit copies.
    
    Daniel Müller's avatar
    Daniel Müller committed
         */
        UdpSocket(const UdpSocket &other) = delete;
    
        /**
    
         * @brief Copying UdpSocket is not allowed. See clone() for explicit copies.
    
    Daniel Müller's avatar
    Daniel Müller committed
         */
        UdpSocket& operator=(const UdpSocket &other) = delete;
    
        /**
         * @brief Create the socket and bind it to the socket address specified in 
         * the constructor.
         * This has to be called before the socket can be used to send or receive 
         * data.
         */
        void bind();
    
        /**
         * @brief Send a number of len bytes as UDP packet to the provided remote 
         * socket address.
         * 
         * @param remote The target address and port to which the UDP packet will 
         * be sent.
         * @param data Pointer to at least len bytes that will be sent as UDP packet.
         * @param len The number of bytes that will be sent.
         *  
         * @return The number of bytes that were actually sent.
         */
        ssize_t sendTo(const SockAddr &remote, const void *data, size_t len);
    
        /**
         * @brief Same as sendTo(SockAddr, data, len) but the SockAddr is created 
         * from the provided parameters.
         * 
         * @see SockAddr
         */
        ssize_t sendTo(const std::string &remoteAddr, uint16_t port, const void *data, size_t len);
    
        /**
         * @brief Same as sendTo(SockAddr, data, len) but the SockAddr is created 
         * from the provided parameters.
         * 
         * @see SockAddr
         */
        ssize_t sendTo(const std::string &remoteAddrPort, const void *data, size_t len);
    
        /**
         * @brief Receive a UDP packet and copy a maximum number of len bytes from 
         * the packet payload into data. Store the senders origin socket address 
         * into remote.
         * 
         * @param data Pointer to at least len bytes of data in which the payload 
         * will be copied.
         * @param len The maximum number of bytes that can be copied into data.
         * @param remote A reference to a SockAddr that is used to store the origin 
         * of the UDP packet.
         * 
    
         * @return The number of bytes that were actually copied.
    
    Daniel Müller's avatar
    Daniel Müller committed
         */
        ssize_t receive(void *data, size_t len, SockAddr &remote);
    
        /**
         * @brief Receive a UDP packet and copy a maximum number of len bytes from 
         * the packet payload into data. The packets origin is not stored.
         * 
         * @param data Pointer to at least len bytes of data in which the payload 
         * will be copied.
         * @param len The maximum number of bytes that can be copied into data.
         * 
    
         * @return The number of bytes that were actually copied.
    
    Daniel Müller's avatar
    Daniel Müller committed
         */
        ssize_t receive(void *data, size_t len);
    
    
        /**
         * @brief Receive a UDP packet and copy a maximum number of len bytes from 
         * the packet payload into data. Store the senders origin socket address 
         * into remote. If the timeout occurs, 0 is returned. 
         * 
         * @param data Pointer to at least len bytes of data in which the payload 
         * will be copied.
         * @param len The maximum number of bytes that can be copied into data.
         * @param remote A reference to a SockAddr that is used to store the origin 
         * of the UDP packet.
         * @param timeoutMs The number of milliseconds before a timeout occurs. 
         * 
         * @return The number of bytes that were actually copied, or 0 if a timeout
         * occured.
         */
        ssize_t receiveTimeout(void *data, size_t len, SockAddr &remote, int timeoutMs);
    
        /**
         * @brief Receive a UDP packet and copy a maximum number of len bytes from 
         * the packet payload into data. The packets origin is not stored. If the 
         * timeout occurs, 0 is returned. 
         * 
         * @param data Pointer to at least len bytes of data in which the payload 
         * will be copied.
         * @param len The maximum number of bytes that can be copied into data.
         * @param timeoutMs The number of milliseconds before a timeout occurs. 
         * 
         * @return The number of bytes that were actually copied, or 0 if a timeout
         * occured.
         */
        ssize_t receiveTimeout(void *data, size_t len, int timeoutMs);
    
    
    Daniel Müller's avatar
    Daniel Müller committed
        /**
         * @brief Check if the socket is closed or open. Open in this case means 
         * bound and ready to send / receive.
         * 
         * @return True if the socket was not yet opened, or if it has been closed.
         */
        bool isClosed() const;
    
        /**
         * @brief Close the listening socket. After this, the UdpSocket can no 
         * longer be used to send or receive packets without calling bind again.
         */
        void close();
    
    
        /**
         * @brief Set the behavior for when the UdpSocket is destroyed. If autoclose
         * is enabled, the socket is closed on destruct. If autoclose is disabled, the
         * socket will not be closed automatically.
         * 
         * @param autoclose Enable or disable the autoclose functionality.
         */
        void setAutoclose(bool autoclose);
    
        /**
         * @brief Create a clone of this socket wrapper object. The clone and the 
         * original will share the same underlying socket and file descriptor. 
         * If one of the instances closes the socket, the socket will be closed 
         * for both. The other instance will not be notified about this, but instead
         * socket operations will just fail. Due to this, it might be a good idea to  
         * disabel autoclose and manually close the socket.
         * 
         * @return A clone of this UdpSocket that shares the same underlying socket.
         */
        UdpSocket clone();
    
    
    Daniel Müller's avatar
    Daniel Müller committed
    };
    
    
    
    } // namespace netlib
    
    
    Daniel Müller's avatar
    Daniel Müller committed
    #endif // _UDPSOCKET_HPP