TCP/IP协议-TCP类的编写

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

 

CTCP.代码如下:

 

  
    
1 /* **************************************************
2 *作 者:温子祺
3 *联系方式:[email protected]
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 *联系方式:[email protected]
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 }

 

 

 

 

 

你可能感兴趣的:(TCP/IP)