$search
00001 #ifndef CASTOR_NET_CHANNELS_UDP_H 00002 #define CASTOR_NET_CHANNELS_UDP_H 1 00003 00004 #include <set> 00005 00006 #include <boost/enable_shared_from_this.hpp> 00007 #include <boost/thread/mutex.hpp> 00008 #include <boost/thread/condition.hpp> 00009 #include <boost/bind.hpp> 00010 00011 #include <asio.hpp> 00012 00013 #include <CastorChannel.h> 00014 00015 namespace castor { namespace net { namespace channels { 00016 00017 class Udp : public CastorChannel { 00018 00019 private: 00020 00021 asio::ip::udp::socket socket; 00022 00023 asio::ip::udp::endpoint endpoint; 00024 asio::ip::udp::endpoint remoteEndpoint; 00025 00026 boost::condition cond; 00027 boost::mutex monitor; 00028 00029 NetAddressPtr localMcastAddress; 00030 00031 bool localMcastAddressHack; 00032 00033 protected: 00034 00035 Udp(asio::io_service &service); 00036 00037 void handleReceive(const asio::error_code& error, size_t count); 00038 00039 public: 00040 00041 Udp(asio::io_service &service, const NetAddress &a); 00042 00043 virtual ~Udp(); 00044 00045 virtual void setAsync(bool async); 00046 00047 virtual NetAddress getLocalAddress(); 00048 00049 virtual void open(); 00050 virtual void open(const NetAddress &a); 00051 virtual void bind(); 00052 00053 virtual void reuseAddress(bool on); 00054 virtual bool reuseAddress(); 00055 00056 virtual void enableLoopback(bool on); 00057 virtual bool enableLoopback(); 00058 00059 virtual void enableBroadcast(bool on); 00060 virtual bool enableBroadcast(); 00061 00062 virtual void multicastHops(int hops); 00063 virtual int multicastHops(); 00064 00065 virtual void joinGroup(const asio::ip::address &address); 00066 virtual void leaveGroup(const asio::ip::address &address); 00067 00068 virtual void accept() throw(NetException); 00069 virtual void connect() throw(NetException); 00070 00071 virtual void close() throw(NetException); 00072 virtual void close(const NetAddress &address) throw(NetException); 00073 virtual bool isOpen(); 00074 00075 inline size_t receive(char *data, size_t length) { 00076 return this->socket.receive(asio::buffer(data, length)); 00077 } 00078 00079 inline size_t receive(char *data, size_t length, NetAddress &remote) { 00080 00081 asio::ip::udp::endpoint ep; 00082 00083 size_t count = this->socket.receive_from(asio::buffer(data, length), ep); 00084 00085 remote = *NetAddress::create(this->address.getSpicaSpecific(), ep); 00086 00087 return count; 00088 } 00089 00090 inline void send(const char *data, size_t length) { 00091 00092 if ((this->mode == mode_connect) || (this->address.isMulticast())) { 00093 00094 try { 00095 this->socket.send_to(asio::buffer(data, length), this->endpoint); 00096 } catch (...) { 00097 // Silently drop exception 00098 } 00099 00100 } else { 00101 std::cerr << "Udp: unable to send data without remote endpoint in bind mode" << std::endl; 00102 } 00103 } 00104 00105 inline void send(const char *data, size_t length, const NetAddress &remote) { 00106 asio::ip::udp::endpoint ep(remote.getAddress(), remote.getPort()); 00107 00108 try { 00109 this->socket.send_to(asio::buffer(data, length), ep); 00110 } catch (const std::exception &e) { 00111 // Silently drop exception 00112 } 00113 00114 } 00115 }; 00116 00117 } } } 00118 00119 #endif /* CASTOR_NET_CHANNELS_UDP_H */ 00120