Go to the documentation of this file.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
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
00112 }
00113
00114 }
00115 };
00116
00117 } } }
00118
00119 #endif
00120