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
00009
00010
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
00046
00047
00048
00049
00050
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
00062
00063
00064
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
00078
00079
00080
00081
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
00098
00099
00100
00101
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;
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
00129
00130
00131
00132
00133
00134
00135
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)
00145 return false;
00146 } else
00147 *max_len = val;
00148
00149 return true;
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159
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__