zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    项目管理5大过程9大知识域44个定义
    linux centos6.5 修改ip地址
    .Net 6 已知问题集
    第二次阅读作业——程志
    采访大四学长整理笔记
    c#
    团队作业三两感想 by 程志
    搞定3G上网
    高焕堂Android應用框架原理與程式設計代码补遗(一)
    要素类属性内容全角换半角
  • 原文地址:https://www.cnblogs.com/wenziqi/p/1769235.html
Copyright © 2011-2022 走看看