ucommon
|
00001 // Copyright (C) 1999-2005 Open Source Telecom Corporation. 00002 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks. 00003 // 00004 // This program is free software; you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation; either version 2 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this program; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 // 00018 // As a special exception, you may use this file as part of a free software 00019 // library without restriction. Specifically, if other files instantiate 00020 // templates or use macros or inline functions from this file, or you compile 00021 // this file and link it with other files to produce an executable, this 00022 // file does not by itself cause the resulting executable to be covered by 00023 // the GNU General Public License. This exception does not however 00024 // invalidate any other reasons why the executable file might be covered by 00025 // the GNU General Public License. 00026 // 00027 // This exception applies only to the code released under the name GNU 00028 // Common C++. If you copy code from other releases into a copy of GNU 00029 // Common C++, as the General Public License permits, the exception does 00030 // not apply to the code that you add in this way. To avoid misleading 00031 // anyone as to the status of such modified files, you must delete 00032 // this exception notice from them. 00033 // 00034 // If you write modifications of your own for GNU Common C++, it is your choice 00035 // whether to permit this exception to apply to your modifications. 00036 // If you do not wish that, delete this exception notice. 00037 // 00038 00044 #ifndef COMMONCPP_UDP_H_ 00045 #define COMMONCPP_UDP_H_ 00046 00047 #include <cstdio> 00048 00049 #ifndef COMMONCPP_CONFIG_H_ 00050 #include <commoncpp/config.h> 00051 #endif 00052 00053 #ifndef COMMONCPP_STRING_H_ 00054 #include <commoncpp/string.h> 00055 #endif 00056 00057 #ifndef COMMONCPP_ADDRESS_H_ 00058 #include <commoncpp/address.h> 00059 #endif 00060 00061 #ifndef COMMONCPP_SOCKET_H_ 00062 #include <commoncpp/socket.h> 00063 #endif 00064 00065 NAMESPACE_COMMONCPP 00066 00099 class __EXPORT UDPSocket : public Socket 00100 { 00101 private: 00102 inline Error setKeepAlive(bool enable) 00103 {return Socket::setKeepAlive(enable);}; 00104 00105 protected: 00106 #ifdef CCXX_IPV6 00107 union { 00108 struct sockaddr_in6 ipv6; 00109 struct sockaddr_in ipv4; 00110 } peer; 00111 #else 00112 union { 00113 struct sockaddr_in ipv4; 00114 } peer; 00115 #endif 00116 00117 Family family; 00118 00119 public: 00123 UDPSocket(Family family = IPV4); 00124 00128 UDPSocket(const char *name, Family family = IPV4); 00129 00139 UDPSocket(const IPV4Address &bind, tpport_t port); 00140 #ifdef CCXX_IPV6 00141 UDPSocket(const IPV6Address &bind, tpport_t port); 00142 #endif 00143 00147 virtual ~UDPSocket(); 00148 00152 inline Error setLoopback(bool enable) 00153 {return Socket::setLoopbackByFamily(enable, family);} 00154 00158 inline Error setMulticast(bool enable) 00159 {return Socket::setMulticastByFamily(enable, family);} 00160 00164 inline Error setTimeToLive(char ttl) 00165 {return Socket::setTimeToLiveByFamily(ttl, family);} 00166 00174 void setPeer(const IPV4Host &host, tpport_t port); 00175 void connect(const IPV4Host &host, tpport_t port); 00176 #ifdef CCXX_IPV6 00177 void setPeer(const IPV6Host &host, tpport_t port); 00178 void connect(const IPV6Host &host, tpport_t port); 00179 #endif 00180 00188 Socket::Error getInterfaceIndex(const char *ethX,int& InterfaceIndex); 00189 00198 Socket::Error join(const IPV4Multicast &ia,int InterfaceIndex); 00199 00207 ssize_t send(const void *buf, size_t len); 00208 00217 ssize_t receive(void *buf, size_t len, bool reply = false); 00218 00227 IPV4Host getIPV4Peer(tpport_t *port = NULL) const; 00228 inline IPV4Host getPeer(tpport_t *port = NULL) const 00229 {return getIPV4Peer(port);} 00230 00231 #ifdef CCXX_IPV6 00232 IPV6Host getIPV6Peer(tpport_t *port = NULL) const; 00233 #endif 00234 00242 inline ssize_t peek(void *buf, size_t len) 00243 {return ::recv(so, (char *)buf, len, MSG_PEEK);}; 00244 00248 void setPeer(const char *service); 00249 void connect(const char *service); 00250 00255 Error disconnect(void); 00256 }; 00257 00266 class __EXPORT UDPBroadcast : public UDPSocket 00267 { 00268 private: 00269 void setPeer(const IPV4Host &ia, tpport_t port); 00270 00271 Error setBroadcast(bool enable) 00272 {return Socket::setBroadcast(enable);}; 00273 00274 public: 00281 UDPBroadcast(const IPV4Address &ia, tpport_t port); 00282 00289 void setPeer(const IPV4Broadcast &subnet, tpport_t port); 00290 }; 00291 00300 class __EXPORT UDPTransmit : protected UDPSocket 00301 { 00302 private: 00310 Error cConnect(const IPV4Address &ia, tpport_t port); 00311 00312 protected: 00316 UDPTransmit(Family family = IPV4); 00317 00329 UDPTransmit(const IPV4Address &bind, tpport_t port = 5005); 00330 #ifdef CCXX_IPV6 00331 UDPTransmit(const IPV6Address &bind, tpport_t port = 5005); 00332 #endif 00333 00343 Error connect(const IPV4Host &host, tpport_t port); 00344 #ifdef CCXX_IPV6 00345 Error connect(const IPV6Address &host, tpport_t port); 00346 #endif 00347 00357 Error connect(const IPV4Broadcast &subnet, tpport_t port); 00358 00366 Error connect(const IPV4Multicast &mgroup, tpport_t port); 00367 #ifdef CCXX_IPV6 00368 Error connect(const IPV6Multicast &mgroup, tpport_t port); 00369 #endif 00370 00378 inline ssize_t send(const void *buf, size_t len) 00379 {return ::send(so, (const char *)buf, len, MSG_NOSIGNAL);} 00380 00384 inline void endTransmitter(void) 00385 {Socket::endSocket();} 00386 00387 /* 00388 * Get transmitter socket. 00389 * 00390 * @return transmitter. 00391 */ 00392 inline SOCKET getTransmitter(void) 00393 {return so;}; 00394 00395 inline Error setMulticast(bool enable) 00396 {return Socket::setMulticastByFamily(enable, family);} 00397 00398 inline Error setTimeToLive(unsigned char ttl) 00399 {return Socket::setTimeToLiveByFamily(ttl, family);}; 00400 00401 public: 00411 inline ssize_t transmit(const char *buffer, size_t len) 00412 {return ::send(so, buffer, len, MSG_DONTWAIT|MSG_NOSIGNAL);} 00413 00420 inline bool isOutputReady(unsigned long timeout = 0l) 00421 {return Socket::isPending(Socket::pendingOutput, timeout);}; 00422 00423 00424 inline Error setRouting(bool enable) 00425 {return Socket::setRouting(enable);}; 00426 00427 inline Error setTypeOfService(Tos tos) 00428 {return Socket::setTypeOfService(tos);}; 00429 00430 inline Error setBroadcast(bool enable) 00431 {return Socket::setBroadcast(enable);}; 00432 }; 00433 00442 class __EXPORT UDPReceive : protected UDPSocket 00443 { 00444 protected: 00455 UDPReceive(const IPV4Address &bind, tpport_t port); 00456 #ifdef CCXX_IPV6 00457 UDPReceive(const IPV6Address &bind, tpport_t port); 00458 #endif 00459 00469 Error connect(const IPV4Host &host, tpport_t port); 00470 #ifdef CCXX_IPV6 00471 Error connect(const IPV6Host &host, tpport_t port); 00472 #endif 00473 00480 bool isPendingReceive(timeout_t timeout) 00481 {return Socket::isPending(Socket::pendingInput, timeout);}; 00482 00486 inline void endReceiver(void) 00487 {Socket::endSocket();} 00488 00489 inline SOCKET getReceiver(void) const 00490 {return so;}; 00491 00492 inline Error setRouting(bool enable) 00493 {return Socket::setRouting(enable);} 00494 00495 inline Error setMulticast(bool enable) 00496 {return Socket::setMulticastByFamily(enable, family);} 00497 00498 inline Error join(const IPV4Multicast &ia) 00499 {return Socket::join(ia);} 00500 00501 #ifdef CCXX_IPV6 00502 inline Error join(const IPV6Multicast &ia) 00503 {return Socket::join(ia);} 00504 #endif 00505 00506 inline Error drop(const IPV4Multicast &ia) 00507 {return Socket::drop(ia);} 00508 00509 #ifdef CCXX_IPV6 00510 inline Error drop(const IPV6Multicast &ia) 00511 {return Socket::drop(ia);} 00512 #endif 00513 00514 public: 00522 inline ssize_t receive(void *buf, size_t len) 00523 {return ::recv(so, (char *)buf, len, 0);}; 00524 00531 inline bool isInputReady(timeout_t timeout = TIMEOUT_INF) 00532 {return Socket::isPending(Socket::pendingInput, timeout);}; 00533 }; 00534 00545 class __EXPORT UDPDuplex : public UDPTransmit, public UDPReceive 00546 { 00547 public: 00555 UDPDuplex(const IPV4Address &bind, tpport_t port); 00556 #ifdef CCXX_IPV6 00557 UDPDuplex(const IPV6Address &bind, tpport_t port); 00558 #endif 00559 00569 Error connect(const IPV4Host &host, tpport_t port); 00570 #ifdef CCXX_IPV6 00571 Error connect(const IPV6Host &host, tpport_t port); 00572 #endif 00573 00580 Error disconnect(void); 00581 }; 00582 00583 END_NAMESPACE 00584 00585 #endif