TCP/IP协议-UDP类的编写
CUDP类主要包含两个文件,分别为:CUDP.h和CUDP.cpp
CUDP.h代码如下:
1 /***************************************************
2 *作 者:温子祺
3 *联系方式:wenziqi@hotmail.com
4 *说 明:CUDP.h
5 ***************************************************/
6 #ifndef __CUDP_H__
7 #define __CUDP_H__
8 #pragma once
9
10 #include "afxsock.h"
11
12
13
14 class CUDP
15 {
16
17 public:
18
19 CUDP(void);
20 ~CUDP(void);
21
22 BOOL Close(void);
23 BOOL Open (CWnd * pPortOwner,
24 CHAR * szLocalIP,
25 UINT unLocalPort,
26 CHAR * szRemoteIP,
27 UINT unRemotePort,
28 UINT unRecvBufSize,
29 UINT unRecvMsg,
30 UINT unConnectMsg
31 );
32 UINT Send(UCHAR *pSendBytes,UINT unSendLen);
33 UINT Recv(UCHAR *pSendBytes);
34
35 protected:
36
37 BOOL Ready(void)const;
38 BOOL InitSocket(void);
39 BOOL CreateThreadAndEvent(void); //创建线程和事件
40 static
41 DWORD RecvThread(LPVOID lpArg); //接收线程
42
43 private:
44
45 CWnd * m_pOwner;
46 BOOL m_bInit;
47 UCHAR * m_szRecvBuf;
48 UINT m_unRecvBufSize;
49 SOCKET m_ClientSocket;
50
51 HANDLE m_hRecvExitEvent;
52 UINT m_unRecvLength;
53 UINT m_unRecvMsg;
54 UINT m_unConnectMsg;
55
56 SOCKADDR_IN m_saRemote;
57 SOCKADDR_IN m_saLocal;
58
59 };
60
61 #endif
CUDP.CPP代码如下:
1 /***************************************************
2 *作 者:温子祺
3 *联系方式:wenziqi@hotmail.com
4 *说 明:CUDP.cpp
5 ***************************************************/
6 #include "StdAfx.h"
7 #include "CUDP.h"
8 #include <assert.h> //使用断言
9
10 CUDP::CUDP(void)
11 {
12 m_bInit=FALSE;
13 m_pOwner=NULL;
14 m_szRecvBuf=NULL;
15 m_hRecvExitEvent=NULL;
16 }
17
18 CUDP::~CUDP(void)
19 {
20 m_pOwner=NULL;
21 m_szRecvBuf=NULL;
22 m_hRecvExitEvent=NULL;
23 }
24
25 BOOL CUDP::Ready(void)const
26 {
27 return m_bInit;
28 }
29
30 BOOL CUDP::Close(void)
31 {
32 if (m_hRecvExitEvent)
33 {
34 SetEvent(m_hRecvExitEvent);
35 Sleep(10);
36 CloseHandle(m_hRecvExitEvent);
37 m_hRecvExitEvent=NULL;
38 }
39
40 m_bInit=FALSE;
41
42 if (INVALID_SOCKET!=m_ClientSocket)
43 {
44 closesocket(m_ClientSocket);
45
46 if (SOCKET_ERROR==WSACleanup())
47 {
48 TRACE("SOCKET 释放资源失败.......!");
49 return FALSE;
50
51 }
52
53 }
54
55 if (m_szRecvBuf)
56 {
57 delete []m_szRecvBuf;
58 m_szRecvBuf=NULL;
59 }
60
61 return TRUE;
62 }
63
64 BOOL CUDP::InitSocket(void)
65 {
66 WSADATA wsa;
67
68 WORD WinSockVersion=MAKEWORD(1,2);
69
70 if (WSAStartup(WinSockVersion,&wsa)!=NULL)
71 {
72 TRACE("载入Windows Sockets失败...!");
73
74 return FALSE;
75 }
76
77 m_ClientSocket=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
78
79 if (INVALID_SOCKET==m_ClientSocket)
80 {
81 TRACE("创建套接字失败...!");
82
83 if (SOCKET_ERROR==WSACleanup())
84 {
85 TRACE("SOCKET 释放资源失败.......!");
86 }
87
88 return FALSE;
89 }
90
91 return TRUE;
92 }
93
94 BOOL CUDP::Open(CWnd * pPortOwner,
95 CHAR * szLocalIP,
96 UINT unLocalPort,
97 CHAR * szRemoteIP,
98 UINT unRemotePort,
99 UINT unRecvBufSize,
100 UINT unRecvMsg,
101 UINT unConnectMsg)
102 {
103 assert(NULL != pPortOwner);
104
105 m_pOwner = pPortOwner;
106
107 if (Ready())
108 {
109 Close();
110 }
111
112
113
114 if (!InitSocket())
115 {
116 return FALSE;
117 }
118
119 SOCKADDR_IN saLocal,saRemote;
120
121 saLocal.sin_family =AF_INET;
122
123 if (*szLocalIP)
124 {
125 saLocal.sin_addr.s_addr=inet_addr(szLocalIP);
126 }
127 else
128 {
129 saLocal.sin_addr.s_addr=htonl(INADDR_ANY); //客户端地址:全范围
130 }
131
132 saLocal.sin_port =htons(unLocalPort); //客户端端口
133
134
135 saRemote.sin_family =AF_INET;
136 saRemote.sin_addr.s_addr =inet_addr(szRemoteIP);//服务器端IP
137 saRemote.sin_port =htons(unRemotePort); //服务器端端口
138
139 memcpy(&m_saLocal, &saLocal ,sizeof(SOCKADDR_IN));
140 memcpy(&m_saRemote,&saRemote,sizeof(SOCKADDR_IN));
141
142 //-----------------------服务器一定要绑定(客户端不一定要绑定)--------------
143 if (SOCKET_ERROR==bind(m_ClientSocket,(PSOCKADDR)&saLocal,sizeof(SOCKADDR_IN)))
144 {
145 TRACE("绑定IP失败...!");
146
147 closesocket(m_ClientSocket);
148
149 if (SOCKET_ERROR==WSACleanup())
150 {
151 TRACE("SOCKET 释放资源失败.......!");
152 }
153
154 return FALSE;
155 }
156
157 if (!CreateThreadAndEvent())
158 {
159 return FALSE;
160 }
161
162 m_unRecvBufSize=unRecvBufSize;
163
164 if (!m_szRecvBuf)
165 {
166 m_szRecvBuf=new UCHAR[unRecvBufSize];
167 }
168
169 m_unRecvMsg=unRecvMsg;
170 m_unConnectMsg=unConnectMsg;
171 m_bInit=TRUE;
172
173 return TRUE;
174
175 }
176
177 BOOL CUDP::CreateThreadAndEvent(void)
178 {
179 m_hRecvExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL); /* 创建串口接收线程退出事件*/
180
181 if (NULL==m_hRecvExitEvent)
182 {
183 return FALSE;
184 }
185
186 ResetEvent(m_hRecvExitEvent); //设置线程没有退出
187
188 HANDLE hRecvThread=NULL;
189 DWORD dwThreadID =0;
190
191 // 创建串口接收线程
192 hRecvThread=CreateThread(0,
193 0,
194 (LPTHREAD_START_ROUTINE)RecvThread,
195 this,
196 0,
197 &dwThreadID);
198
199 if (NULL==hRecvThread)
200 {
201 return FALSE;
202 }
203
204 CloseHandle(hRecvThread);
205 hRecvThread=NULL;
206
207 return TRUE;
208 }
209
210 DWORD CUDP::RecvThread(LPVOID lpArg)
211 {
212
213 assert(lpArg != NULL);
214
215 CUDP *pArg= (CUDP *)(lpArg);
216
217 assert(pArg != NULL);
218
219 INT rt= 0;
220 INT nSizeOfSockAddIn=0;
221
222 while (1)
223 {
224 if(WaitForSingleObject(pArg->m_hRecvExitEvent,0)==WAIT_OBJECT_0)
225 {
226 break;
227 }
228
229 if (pArg->Ready())
230 {
231 nSizeOfSockAddIn=sizeof(SOCKADDR_IN);
232
233 //recv函数:阻塞线程,不占CPU资源
234 rt=recvfrom(pArg-> m_ClientSocket,
235 (CHAR *)(pArg->m_szRecvBuf),
236 pArg->m_unRecvBufSize,
237 0,
238 (SOCKADDR *)&pArg->m_saRemote,
239 &nSizeOfSockAddIn);
240
241 if (SOCKET_ERROR==rt ||NULL==rt)
242 {
243 TRACE(_T("TCPRecvThread:网络接收数据线程出现套接字错误...!"));
244
245 ::SendMessage((pArg->m_pOwner)->m_hWnd,
246 pArg->m_unConnectMsg,
247 0,
248 0);
249 break;
250 }
251 else if (rt>0)
252 {
253
254 pArg->m_unRecvLength=rt;
255
256 ::SendMessage((pArg->m_pOwner)->m_hWnd,
257 pArg->m_unRecvMsg,
258 0,
259 0);
260
261 }
262 }
263
264 Sleep(1);
265 }
266
267
268 Sleep(10);
269
270 return 0;
271 }
272
273
274 UINT CUDP::Send(UCHAR *pSendBytes,UINT unSendLen)
275 {
276 INT rt=0;
277 UINT cnt=0;
278
279 assert(pSendBytes != NULL);
280 assert(unSendLen != NULL);
281
282
283 while (cnt<unSendLen)
284 {
285 rt=sendto(m_ClientSocket,
286 (CHAR *)(pSendBytes+cnt),
287 (unSendLen-cnt),
288 0,
289 (sockaddr *)&m_saRemote,
290 sizeof(m_saRemote));
291
292 if (SOCKET_ERROR==rt)
293 {
294 TRACE("TCPSend:网络发送数据出现套接字错误...!");
295
296 return 0;
297 }
298
299 cnt+=rt;
300
301 if (cnt<unSendLen)
302 {
303 Sleep(1000);
304 }
305 }
306
307 return cnt;
308 }
309
310 UINT CUDP::Recv(UCHAR *szRecvBuf)
311 {
312 if (NULL == szRecvBuf)
313 {
314 return 0;
315 }
316
317 if (!Ready())
318 {
319 return 0;
320 }
321
322 memcpy(szRecvBuf,m_szRecvBuf,m_unRecvBufSize);
323
324 return m_unRecvLength;
325 }