TCP/IP协议-TCP类的编写

CTCP类主要包含两个文件,分别为:CTCP.h和CTCP.cpp

 

CTCP.代码如下:

 

1 /***************************************************
2 *作 者:温子祺
3 *联系方式:wenziqi@hotmail.com
4 *说 明:CTCP.h
5 ***************************************************/
6 #ifndef __CTCP_H__
7  #define __CTCP_H__
8  #pragma once
9
10 #include "afxsock.h"
11
12
13  class CTCP
14 {
15
16  public:
17
18 CTCP(void);
19 ~CTCP(void);
20
21 BOOL Close(void);
22 BOOL Open (CWnd * pPortOwner,
23 CHAR * szLocalIP,
24 UINT unLocalPort,
25 CHAR * szRemoteIP,
26 UINT unRemotePort,
27 UINT unRecvBufSize,
28 UINT unRecvMsg,
29 UINT unConnectMsg
30 );
31 UINT Send(UCHAR *pSendBytes,UINT unSendLen);
32 UINT Recv(UCHAR *pSendBytes);
33
34  protected:
35
36 BOOL Ready(void)const;
37 BOOL InitSocket(void);
38 BOOL CreateThreadAndEvent(void); //创建线程和事件
39  static
40 DWORD RecvThread(LPVOID lpArg); //接收线程
41  
42  private:
43
44 CWnd * m_pOwner;
45 BOOL m_bInit;
46 UCHAR * m_szRecvBuf;
47
48 SOCKET m_ClientSocket;
49
50 HANDLE m_hRecvExitEvent;
51
52 UINT m_unRecvBufSize;
53 UINT m_unRecvLength;
54 UINT m_unRecvMsg;
55 UINT m_unConnectMsg;
56
57
58 };
59
60  #endif

 

CTCP.cpp代码如下:

 

1 /***************************************************
2 *作 者:温子祺
3 *联系方式:wenziqi@hotmail.com
4 *说 明:CTCP.cpp
5 ***************************************************/
6 #include "StdAfx.h"
7 #include "CTCP.h"
8 #include <assert.h> //使用断言
9
10 CTCP::CTCP(void)
11 {
12 m_pOwner=NULL;
13 m_szRecvBuf=NULL;
14 m_hRecvExitEvent=NULL;
15 m_bInit=FALSE;
16 }
17
18 CTCP::~CTCP(void)
19 {
20 m_pOwner=NULL;
21 m_szRecvBuf=NULL;
22 m_hRecvExitEvent=NULL;
23 }
24 BOOL CTCP::Ready(void)const
25 {
26 return m_bInit;
27 }
28
29
30 BOOL CTCP::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 CTCP::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_STREAM, 0);
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 CTCP::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 if (!InitSocket())
113 {
114 return FALSE;
115 }
116
117 SOCKADDR_IN saLocal,saRemote;
118
119 saLocal.sin_family =AF_INET;
120
121 if (*szLocalIP)
122 {
123 saLocal.sin_addr.s_addr=inet_addr(szLocalIP);
124 }
125 else
126 {
127 saLocal.sin_addr.s_addr=htonl(INADDR_ANY); //客户端地址:全范围
128 }
129
130 saLocal.sin_port =htons(unLocalPort); //客户端端口
131
132
133 saRemote.sin_family =AF_INET;
134 saRemote.sin_addr.s_addr =inet_addr(szRemoteIP);//服务器端IP
135 saRemote.sin_port =htons(unRemotePort); //服务器端端口
136
137 //-----------------------服务器一定要绑定(客户端不一定要绑定)--------------
138 if (SOCKET_ERROR==bind(m_ClientSocket,(PSOCKADDR)&saLocal,sizeof(SOCKADDR_IN)))
139 {
140 TRACE("绑定IP失败...!");
141
142 closesocket(m_ClientSocket);
143
144 if (SOCKET_ERROR==WSACleanup())
145 {
146 TRACE("SOCKET 释放资源失败.......!");
147 }
148
149 return FALSE;
150 }
151
152
153 if (SOCKET_ERROR==connect(m_ClientSocket,(PSOCKADDR)&saRemote,sizeof(SOCKADDR_IN)))
154 {
155 TRACE("连接服务器失败...!");
156
157 closesocket(m_ClientSocket);
158
159 if (SOCKET_ERROR==WSACleanup())
160 {
161 TRACE("SOCKET 释放资源失败.......!");
162 }
163
164 return FALSE;
165 }
166
167 if (!CreateThreadAndEvent())
168 {
169 return FALSE;
170 }
171
172 m_unRecvBufSize=unRecvBufSize;
173
174 if (!m_szRecvBuf)
175 {
176 m_szRecvBuf=new UCHAR[unRecvBufSize];
177 }
178
179 m_unRecvMsg =unRecvMsg;
180 m_unConnectMsg=unConnectMsg;
181
182 m_bInit=TRUE;
183
184 return TRUE;
185
186 }
187
188 BOOL CTCP::CreateThreadAndEvent(void)
189 {
190 m_hRecvExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL); /* 创建串口接收线程退出事件*/
191
192 if (NULL==m_hRecvExitEvent)
193 {
194 return FALSE;
195 }
196
197 ResetEvent(m_hRecvExitEvent); //设置线程没有退出
198
199 HANDLE hRecvThread=NULL;
200 DWORD dwThreadID =0;
201
202 // 创建串口接收线程
203 hRecvThread=CreateThread(0,
204 0,
205 (LPTHREAD_START_ROUTINE)RecvThread,
206 this,
207 0,
208 &dwThreadID);
209
210 if (NULL==hRecvThread)
211 {
212 return FALSE;
213 }
214
215 CloseHandle(hRecvThread);
216 hRecvThread=NULL;
217
218 return TRUE;
219 }
220
221 DWORD CTCP::RecvThread(LPVOID lpArg)
222 {
223 assert(NULL != lpArg);
224
225 CTCP *pArg=(CTCP *)lpArg;
226
227 assert(NULL != pArg);
228
229 INT rt=0;
230
231 while (1)
232 {
233 if (WaitForSingleObject(pArg->m_hRecvExitEvent,0)==WAIT_OBJECT_0)
234 {
235 break; //线程退出
236 }
237
238 if (pArg->Ready())
239 {
240 memset(pArg->m_szRecvBuf,0,sizeof(pArg->m_szRecvBuf));
241
242 //recv函数:阻塞线程,不占CPU资源
243 rt=recv(pArg->m_ClientSocket,(CHAR *)(pArg->m_szRecvBuf),pArg->m_unRecvBufSize,NULL);
244
245 if (SOCKET_ERROR==rt || NULL==rt)
246 {
247 TRACE("TCPRecvThread:网络接收数据线程出现套接字错误...!");
248
249 ::SendMessage((pArg->m_pOwner)->m_hWnd,
250 pArg->m_unConnectMsg,
251 0,
252 0);
253
254 break;
255 }
256 else if (rt>0)
257 {
258 pArg->m_unRecvLength=rt;
259
260 ::SendMessage((pArg->m_pOwner)->m_hWnd,
261 pArg->m_unRecvMsg,
262 0,
263 0);
264
265 }
266 }
267
268 Sleep(1);
269 }
270
271 Sleep(10); //让线程安全退出
272
273 return 0;
274 }
275
276
277 UINT CTCP::Send(UCHAR *pSendBytes,UINT unSendLen)
278 {
279 INT rt=0;
280 UINT cnt=0;
281
282 assert(pSendBytes != NULL);
283 assert(unSendLen != NULL);
284
285
286 while (cnt<unSendLen)
287 {
288 rt=send(m_ClientSocket,
289 (CHAR *)(pSendBytes+cnt),
290 (unSendLen-cnt),
291 NULL);
292
293 if (SOCKET_ERROR==rt)
294 {
295 TRACE("TCPSend:网络发送数据出现套接字错误...!");
296
297 return 0;
298 }
299
300 cnt+=rt;
301
302 if (cnt<unSendLen)
303 {
304 Sleep(1000);
305 }
306 }
307
308 return cnt;
309 }
310
311 UINT CTCP::Recv(UCHAR *szRecvBuf)
312 {
313 if (NULL == szRecvBuf)
314 {
315 return 0;
316 }
317
318 if (!Ready())
319 {
320 return 0;
321 }
322
323 memcpy(szRecvBuf,m_szRecvBuf,m_unRecvBufSize);
324
325 return m_unRecvLength;
326 }

 

 

 

 

 

posted @ 2010-07-01 15:52  温子祺  阅读(1416)  评论(0编辑  收藏  举报