zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    工作中常用,实用工具推荐!
    “如何管理好你的时间”
    经典SQL语句大全(绝对的经典eweqweqwe)
    第三节 MongoDB下samus源码初探
    ASP.NET(C#)常用数据加密和解密方法汇总
    全自动时代:JavaScript自动压缩插件
    SQL Server 获取所有表和数据的批量操作
    千万级别数据表,单列索引和多列索引性能对比
    第二节 为什么用MongoDB及.NET开发入门
    vs2005手机开发环境的配置
  • 原文地址:https://www.cnblogs.com/wenziqi/p/1769230.html
Copyright © 2011-2022 走看看