Panda3D
|
00001 #ifndef __SOCKET_UDP_INCOMING_H__ 00002 #define __SOCKET_UDP_INCOMING_H__ 00003 00004 #include "pandabase.h" 00005 #include "socket_ip.h" 00006 00007 ///////////////////////////////////////////////////////////////////// 00008 // Class : Socket_UDP_Incoming 00009 // 00010 // Description : Base functionality for a UDP Reader 00011 // 00012 // 00013 ///////////////////////////////////////////////////////////////////// 00014 class EXPCL_PANDA_NATIVENET Socket_UDP_Incoming : public Socket_IP 00015 { 00016 PUBLISHED: 00017 inline Socket_UDP_Incoming() { } 00018 00019 inline bool OpenForInput(const Socket_Address & address); 00020 inline bool OpenForInputMCast(const Socket_Address & address ); 00021 inline bool GetPacket(char * data, int *max_len, Socket_Address & address); 00022 inline bool SendTo(const char * data, int len, const Socket_Address & address); 00023 inline bool InitNoAddress(); 00024 inline bool SetToBroadCast(); 00025 00026 public: 00027 static TypeHandle get_class_type() { 00028 return _type_handle; 00029 } 00030 static void init_type() { 00031 Socket_IP::init_type(); 00032 register_type(_type_handle, "Socket_UDP_Incoming", 00033 Socket_IP::get_class_type()); 00034 } 00035 virtual TypeHandle get_type() const { 00036 return get_class_type(); 00037 } 00038 virtual TypeHandle force_init_type() {init_type(); return get_class_type();} 00039 00040 private: 00041 static TypeHandle _type_handle; 00042 }; 00043 00044 ////////////////////////////////////////////////////////////// 00045 // Function name : Socket_UDP_Incoming::tToBroadCast 00046 // Description : Flips the OS bits that allow for brodcast 00047 // packets to com in on this port 00048 // 00049 // Return type : bool 00050 // Argument : void 00051 ////////////////////////////////////////////////////////////// 00052 inline bool Socket_UDP_Incoming::SetToBroadCast() 00053 { 00054 int optval = 1; 00055 00056 if (setsockopt(_socket, SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof(optval)) != 0) 00057 return false; 00058 return true; 00059 } 00060 ////////////////////////////////////////////////////////////// 00061 // Function name : Socket_UDP_Incoming::InitNoAddress 00062 // Description : Set this socket to work with out a bound external address.. 00063 // Return type : inline bool 00064 // Argument : void 00065 ////////////////////////////////////////////////////////////// 00066 inline bool Socket_UDP_Incoming::InitNoAddress() 00067 { 00068 Close(); 00069 _socket = DO_NEWUDP(); 00070 if (_socket == BAD_SOCKET) 00071 return false; 00072 00073 return true; 00074 } 00075 00076 //////////////////////////////////////////////////////////////////// 00077 // Function name : Socket_UDP_Incoming::OpenForInput 00078 // Description : Starts a UDP socket listening on a port 00079 // 00080 // Return type : bool 00081 // Argument : NetAddress & address 00082 //////////////////////////////////////////////////////////////////// 00083 inline bool Socket_UDP_Incoming::OpenForInput(const Socket_Address & address) 00084 { 00085 Close(); 00086 _socket = DO_NEWUDP(); 00087 if (_socket == BAD_SOCKET) 00088 return ErrorClose(); 00089 00090 if (DO_BIND(_socket, &address.GetAddressInfo()) != 0) 00091 return ErrorClose(); 00092 00093 return true; 00094 } 00095 00096 //////////////////////////////////////////////////////////////////// 00097 // Function name : Socket_UDP_Incoming::OpenForInput 00098 // Description : Starts a UDP socket listening on a port 00099 // 00100 // Return type : bool 00101 // Argument : NetAddress & address 00102 //////////////////////////////////////////////////////////////////// 00103 inline bool Socket_UDP_Incoming::OpenForInputMCast(const Socket_Address & address) 00104 { 00105 Close(); 00106 _socket = DO_NEWUDP(); 00107 if (_socket == BAD_SOCKET) 00108 return ErrorClose(); 00109 00110 Socket_Address wa1(address.get_port()); 00111 if (DO_BIND(_socket, &wa1.GetAddressInfo()) != 0) 00112 return ErrorClose(); 00113 00114 struct ip_mreq imreq; 00115 memset(&imreq,0,sizeof(imreq)); 00116 imreq.imr_multiaddr.s_addr = address.GetAddressInfo().sin_addr.s_addr; 00117 imreq.imr_interface.s_addr = INADDR_ANY; // use DEFAULT interface 00118 00119 int status = setsockopt(GetSocket(), IPPROTO_IP, IP_ADD_MEMBERSHIP, 00120 (const char *)&imreq, sizeof(struct ip_mreq)); 00121 00122 if(status != 0) 00123 return false; 00124 return true; 00125 } 00126 00127 //////////////////////////////////////////////////////////////////// 00128 // Function name : Socket_UDP_Incoming::GetPacket 00129 // Description : Grabs a dataset off the listening UDP socket 00130 // and fills in the source address information 00131 // 00132 // Return type : bool 00133 // Argument : char * data 00134 // Argument : int *max_len 00135 // Argument : NetAddress & address 00136 //////////////////////////////////////////////////////////////////// 00137 inline bool Socket_UDP_Incoming::GetPacket(char * data, int *max_len, Socket_Address & address) 00138 { 00139 int val = DO_RECV_FROM(_socket, data, *max_len, &address.GetAddressInfo()); 00140 *max_len = 0; 00141 00142 if (val <= 0) 00143 { 00144 if (GetLastError() != LOCAL_BLOCKING_ERROR) // im treating a blocking error as a 0 lenght read 00145 return false; 00146 } else 00147 *max_len = val; 00148 00149 return true; 00150 } 00151 00152 //////////////////////////////////////////////////////////////////// 00153 // Function name : SocketUDP_Outgoing::SendTo 00154 // Description : Send data to specified address 00155 // 00156 // Return type : inline bool 00157 // Argument : char * data 00158 // Argument : int len 00159 // Argument : NetAddress & address 00160 //////////////////////////////////////////////////////////////////// 00161 inline bool Socket_UDP_Incoming::SendTo(const char * data, int len, const Socket_Address & address) 00162 { 00163 return (DO_SOCKET_WRITE_TO(_socket, data, len, &address.GetAddressInfo()) == len); 00164 } 00165 00166 00167 00168 00169 #endif //__SOCKET_UDP_INCOMING_H__