1 /*******************************************************************************
2 * File Name : HLH_UDPSock.cpp
5 * Created Time : 2009-10-10 16:36:17
7 ******************************************************************************/
12 /*******************************************************************************
13 * Desc : Includes Files
14 ******************************************************************************/
16 #include "HLH_utils/HLH_UDPSock.h"
19 /*******************************************************************************
20 * Desc : Macro Definations
21 ******************************************************************************/
24 /*******************************************************************************
25 * Desc : Type Definations
26 ******************************************************************************/
29 /*******************************************************************************
30 * Desc : Global Variables
31 ******************************************************************************/
34 /*******************************************************************************
35 * Desc : File Variables
36 ******************************************************************************/
43 /******************************************************************************
44 * Desc : Member Functions
45 ******************************************************************************/
51 /******************************************************************************
52 * Func : HLH_UDPSock::HLH_UDPSock
53 * Desc : Constuctor of HLH_UDPSock
56 ******************************************************************************/
57 HLH_UDPSock::HLH_UDPSock ()
64 /******************************************************************************
65 * Func : HLH_UDPSock::~HLH_UDPSock
66 * Desc : Deconstructor of HLH_UDPSock
69 ******************************************************************************/
70 HLH_UDPSock::~HLH_UDPSock ()
79 /******************************************************************************
81 ******************************************************************************/
87 /******************************************************************************
88 * Func : HLH_UDPSock::Create
89 * Desc : Create UDP socket and bind it to zhsBindAddr,
90 * then create thread to handle receive event
91 * Args : zhsBindAddr address of bindding
92 * Outs : If success return 0, otherwise return error code.
93 ******************************************************************************/
94 int HLH_UDPSock::Create (const HLH_SockAddr
&zhsBindAddr
)
99 // Lock before process
102 // Check if this instance created
104 // Unlock this instance
105 m_zhmMutex
.Unlock ();
107 HLH_DEBUG ( HLH_DEBUG_MAIN
, ("already created") );
108 return HLH_UDPSOCK_ERR_ALREADY_CREATED
;
111 // Init supper class HLH_Sock first
112 nRetVal
= HLH_Sock::Create (HLH_SOCK_TYPE_DGRAM
, zhsBindAddr
, false);
114 HLH_DEBUG ( HLH_DEBUG_MAIN
, ("create HLH_Sock failed") );
118 // Clear the receive handler list
119 m_slRecvHandlerList
.clear ();
121 // Start receive thread
122 nRetVal
= m_zhtRecvThread
.Start (RecvThreadFunc
, this);
124 HLH_DEBUG ( HLH_DEBUG_MAIN
, ("start received thread failed") );
128 // Notify that this instance created
130 m_bConnected
= false;
132 // Unlock after process
133 m_zhmMutex
.Unlock ();
139 // Close the socket if needed
140 if ( HLH_Sock::IsCreated () ) {
141 HLH_Sock::Destroy ();
144 // Unlock after process
145 m_zhmMutex
.Unlock ();
147 return HLH_UDPSOCK_ERR_CANT_CREATE
;
151 /******************************************************************************
152 * Func : HLH_UDPSock::Destroy
153 * Desc : Destroy this UDP socket
156 ******************************************************************************/
157 void HLH_UDPSock::Destroy ()
159 // Stop receive thread
160 m_zhtRecvThread
.Stop ();
162 // Lock this instance
166 // Check if this instance created
168 // Unlock this instance
169 m_zhmMutex
.Unlock ();
174 // Clear receiver list
175 m_slRecvHandlerList
.clear ();
177 // Destroy this socket
178 HLH_Sock::Destroy ();
181 m_bConnected
= false;
183 // Unlock this instance
184 m_zhmMutex
.Unlock ();
188 /******************************************************************************
189 * Func : HLH_UDPSock::IsCreated
190 * Desc : Whether this instance created
192 * Outs : If success return 0, otherwise return error code.
193 ******************************************************************************/
194 bool HLH_UDPSock::IsCreated ()
199 bCreated
= m_bCreated
;
200 m_zhmMutex
.Unlock ();
208 /******************************************************************************
209 * Func : HLH_UDPSock::AddRecvHandler
210 * Desc : Add receive handler to this socket
211 * Args : zorOnRecv Funtion to handle receive event
212 * pvOnRecvParam Parameter to \c zorOnRecv ()
213 * Outs : if success, return 0, otherwise return error code
214 ******************************************************************************/
215 void HLH_UDPSock::AddRecvHandler (OnRecvFunc zorOnRecv
, void *pvOnRecvParam
)
218 RecvHandler zrhRecvHandler
;
220 // Lock before process
223 // Put this handler into the list
224 zrhRecvHandler
.m_zorOnRecv
= zorOnRecv
;
225 zrhRecvHandler
.m_pvOnRecvParam
= pvOnRecvParam
;
227 m_slRecvHandlerList
.push_back (zrhRecvHandler
);
229 // Lock after process
230 m_zhmMutex
.Unlock ();
234 /******************************************************************************
235 * Func : HLH_UDPSock::DelRecvHandler
236 * Desc : Delete receive handler from receive handler list
237 * Args : zorOnRecv Funtion to handle receive event
238 * pvOnRecvParam Parameter to \c zorOnRecv ()
240 ******************************************************************************/
241 void HLH_UDPSock::DelRecvHandler (OnRecvFunc zorOnRecv
, void *pvOnRecvParam
)
244 RecvHandler zrhRecvHandler
;
246 // Lock before process
249 // Remove this receiver handler
250 zrhRecvHandler
.m_zorOnRecv
= zorOnRecv
;
251 zrhRecvHandler
.m_pvOnRecvParam
= pvOnRecvParam
;
253 m_slRecvHandlerList
.remove (zrhRecvHandler
);
255 // Unlock after process
256 m_zhmMutex
.Unlock ();
260 /******************************************************************************
261 * Func : HLH_UDPSock::ClearRecvHandlerList
262 * Desc : Clear the receive handler list
265 ******************************************************************************/
266 void HLH_UDPSock::ClearRecvHandlerList ()
268 // Lock before process
271 // Clear the receive handler list
272 m_slRecvHandlerList
.clear ();
274 // Unlock after process
275 m_zhmMutex
.Unlock ();
278 /******************************************************************************
279 * Func : HLH_UDPSock::__RecvThreadFunc
280 * Desc : Thread function to call receive handler functions
281 * Args : zhtRecvThread Thread that call \c RecvThreadFunc ()
283 ******************************************************************************/
284 void HLH_UDPSock::__RecvThreadFunc ( HLH_Thread
&zhtRecvThread
)
291 HLH_Time zhtPollTime
;
293 UINT8 acRecvBuf
[HLH_UDPSOCK_MAX_RECEIVE_LENGTH
];
294 HLH_SockAddr zhsPeerAddr
;
295 HLH_SockAddr zhsConnAddr
;
297 std::list
<RecvHandler
>::iterator slIt
;
299 // Signal to zhtRecvThread that this thread functions runned
300 zhtRecvThread
.ThreadStarted ();
304 // Can't process socket not created
305 if ( !IsCreated () ) {
306 HLH_DEBUG ( HLH_DEBUG_MAIN
, ("not created") );
313 // Poll for receive events
314 unPollType
= HLH_SOCK_POLL_READ
;
315 zhtPollTime
.SetTime (HLH_UDPSOCK_DEFAULT_POLLWAIT_SECONDS
, 0);
317 nRetVal
= PollWait (unPollType
, zhtPollTime
);
319 // If there is any data received
323 nRetVal
= RecvFrom (acRecvBuf
, sizeof(acRecvBuf
), zhsPeerAddr
);
325 // XXX: do nothing if receive error
330 // If connected, check the source ip, otherwise accept all
331 nRetVal
= GetConnectAddr (zhsConnAddr
);
332 if ( nRetVal
< 0 || zhsConnAddr
== zhsPeerAddr
) {
333 // Call receive handler call back function
334 for ( slIt
= m_slRecvHandlerList
.begin ();
335 slIt
!= m_slRecvHandlerList
.end (); slIt
++ ) {
336 slIt
->m_zorOnRecv (slIt
->m_pvOnRecvParam
, acRecvBuf
, unLen
, zhsPeerAddr
);
339 HLH_DEBUG ( HLH_DEBUG_MAIN
, ("ignore package") );
345 // Check if stop request
346 if ( zhtRecvThread
.IsStopping () ) {
355 /******************************************************************************
356 * Func : HLH_UDPSock::RecvThreadFunc
357 * Desc : Wrapper of __RecvThreadFunc
358 * Args : zhtRecvThread Thread that call this function
359 * Outs : Always return NULL.
360 ******************************************************************************/
361 void * HLH_UDPSock::RecvThreadFunc (HLH_Thread
&zhtRecvThread
, void *pvThis
)
363 ASSERT (pvThis
!= NULL
);
364 ( (HLH_UDPSock
*) pvThis
)->__RecvThreadFunc (zhtRecvThread
);
369 /******************************************************************************
370 * Func : HLH_UDPSock::Connect
371 * Desc : Reload of HLH_Sock::Connect ()
372 * Args : zhsPeekAddr address to connect
373 * Outs : if success, return 0, otherwise return error code
374 ******************************************************************************/
375 int HLH_UDPSock::Connect (const HLH_SockAddr
&zhsSockAddr
)
379 // Lock this instance
382 nRetVal
= HLH_Sock::Connect (zhsSockAddr
);
387 // Notify that this instance is created
389 m_zhsConnectAddr
= zhsSockAddr
;
391 // Unlock this instance
392 m_zhmMutex
.Unlock ();
397 // Unlock this instance
398 m_zhmMutex
.Unlock ();
400 return HLH_UDPSOCK_ERR_FAILED
;
403 /******************************************************************************
404 * Func : HLH_UDPSock::GetConnectAddr
405 * Desc : Get the address of peer if connected
406 * Args : zhsConnectAddr Space to save the address get
407 * Outs : If success return 0, otherwise return error code.
408 ******************************************************************************/
409 int HLH_UDPSock::GetConnectAddr (HLH_SockAddr
& zhsConnectAddr
)
411 // Lock this instance
413 if (!m_bCreated
|| !m_bConnected
) {
414 // Unlock this instance
415 m_zhmMutex
.Unlock ();
416 HLH_DEBUG ( HLH_DEBUG_UTILS
, ("not connected") );
417 return HLH_UDPSOCK_ERR_NOT_CREATED
;
420 zhsConnectAddr
= m_zhsConnectAddr
;
422 // Unlock this instance
423 m_zhmMutex
.Unlock ();