From a15cf65c44d5c224169c32ef5495b68c758134b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 18 May 2014 16:08:14 +0200 Subject: Imported Upstream version 3.3.0.2 --- libcult/cult/os/net/ipv4/datagram-socket.hxx | 282 +++++++++++++++++++++++++++ 1 file changed, 282 insertions(+) create mode 100644 libcult/cult/os/net/ipv4/datagram-socket.hxx (limited to 'libcult/cult/os/net/ipv4/datagram-socket.hxx') diff --git a/libcult/cult/os/net/ipv4/datagram-socket.hxx b/libcult/cult/os/net/ipv4/datagram-socket.hxx new file mode 100644 index 0000000..2aad43f --- /dev/null +++ b/libcult/cult/os/net/ipv4/datagram-socket.hxx @@ -0,0 +1,282 @@ +// file : cult/os/net/ipv4/datagram-socket.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CULT_OS_NET_IPV4_DATAGRAM_SOCKET_HXX +#define CULT_OS_NET_IPV4_DATAGRAM_SOCKET_HXX + +#include + +#include +#include +#include + +#include // close +#include // socket, bind, sendto, revcfrom + +namespace Cult +{ + namespace OS + { + namespace Net + { + namespace IPv4 + { + class DatagramSocket: public virtual Net::DatagramSocket + { + public: + virtual + ~DatagramSocket () + { + ::close (sock_); + } + + DatagramSocket () + { + sock_ = ::socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); + + if (sock_ == -1) + throw Exception (); //@@ + } + + DatagramSocket (Address const& addr) + { + sock_ = ::socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); + + if (sock_ == -1) + throw Exception (); //@@ + + if (::bind (sock_, addr.raw_addr (), addr.raw_size ()) == -1) + throw Exception (); //@@ + } + + public: + virtual sa_family_t + familiy () const + { + return AF_INET; + } + + virtual Int + protocol () const + { + return IPPROTO_UDP; + } + + // Options. + // + public: + Size + recv_buffer_size () const + { + Int r; + socklen_t s (sizeof (r)); + + if (::getsockopt (sock_, + SOL_SOCKET, + SO_RCVBUF, + &r, + &s) == -1) + { + throw Exception (); //@@ + } + + return static_cast (r); + } + + Void + recv_buffer_size (Size size) + { + Int r (static_cast (size)); + + if (::setsockopt (sock_, + SOL_SOCKET, + SO_RCVBUF, + &r, + sizeof (r)) == -1) + { + throw Exception (); + } + } + + Size + send_buffer_size () const + { + Int r; + socklen_t s (sizeof (r)); + + if (::getsockopt (sock_, + SOL_SOCKET, + SO_SNDBUF, + &r, + &s) == -1) + { + throw Exception (); + } + + return static_cast (r); + } + + void + send_buffer_size (Size size) + { + Int r (static_cast (size)); + + if (::setsockopt (sock_, + SOL_SOCKET, + SO_SNDBUF, + &r, + sizeof (r)) == -1) + { + throw Exception (); + } + } + + public: + Void + connect (Address const& addr) + { + if (::connect (sock_, addr.raw_addr (), addr.raw_size ()) == -1) + throw Exception (); + } + + Address + address () const + { + sockaddr_in raw_addr; + socklen_t raw_size (sizeof (raw_addr)); + + if (::getsockname (sock_, + reinterpret_cast (&raw_addr), + &raw_size) == -1) + { + throw Exception (); + } + + return Address (raw_addr); + } + + + public: + virtual Size + send (Void const* buf, Size size, Net::Address const& addr) + { + if (addr.familiy () != familiy ()) + throw InvalidAddress (); + + return send (buf, size, dynamic_cast
(addr)); + } + + virtual Size + send (Void const* buf, Size size, Address const& addr) + { + ssize_t n (::sendto (sock_, + buf, + size, + 0, + addr.raw_addr (), + addr.raw_size ())); + + if (n == -1) + throw Exception (); + + return static_cast (n); + } + + virtual Size + recv (Void* buf, Size size) + { + ssize_t n (::recvfrom (sock_, buf, size, 0, 0, 0)); + + if (n == -1) + throw Exception (); + + return static_cast (n); + } + + virtual Size + recv (Void* buf, Size size, Address& addr) + { + sockaddr_in raw_addr; + socklen_t raw_size (sizeof (raw_addr)); + + ssize_t n (::recvfrom (sock_, + buf, + size, + 0, + reinterpret_cast (&raw_addr), + &raw_size)); + + if (n == -1) + throw Exception (); + + addr = Address (raw_addr); + + return static_cast (n); + } + + virtual Size + peek (Void* buf, Size size, Address& addr) + { + sockaddr_in raw_addr; + socklen_t raw_size (sizeof (raw_addr)); + + ssize_t n (::recvfrom (sock_, + buf, + size, + MSG_PEEK, + reinterpret_cast (&raw_addr), + &raw_size)); + + if (n == -1) + throw Exception (); + + addr = Address (raw_addr); + + return static_cast (n); + } + + /* + virtual Boolean + recv (Void* buf, + Size size, + Size& received, + OS::Time const& timeout) + { + fd_set r,e; + + FD_ZERO (&r); + FD_ZERO (&e); + + FD_SET (sock_, &r); + FD_SET (sock_, &e); + + int n = ::pselect (sock_ + 1, &r, 0, &e, &timeout.timespec (), 0); + + if (n > 0) + { + recv_size = recv (buf, buf_size); + return true; + } + else if (n == 0) // timeout + { + return false; + } + else + { + throw Failure ("pselect"); + } + } + */ + + protected: + Int sock_; + }; + } + } + } +} + + +#endif // CULT_OS_NET_IPV4_DATAGRAM_SOCKET_HXX -- cgit v1.2.3