Panda3D

socket_udp_incoming.h

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__
 All Classes Functions Variables Enumerations