C++套接字类CxUdpSocket的设计

这是一个小巧的C++套接字类,类名、函数名和变量名均采用匈牙利命名法。小写的x代表我的姓氏首字母(谢欣能),个人习惯而已,如有雷同,纯属巧合。

CxUdpSocket的定义如下:

class XIOCTRL_CLASS CxUdpSocket : public CxSocket
{
public:
CxUdpSocket();
virtual ~CxUdpSocket();
void operator=(SOCKET s) { m_socket = s; } public:
BOOL Bind(int nPort);
BOOL Disbind();
BOOL IsBinded(); BOOL SendTo(LPCSTR lpszIPAddr, LPBYTE lpbtData, DWORD dwSize);
BOOL RecvFrom(LPSTR lpszIPAddr, LPBYTE lpbtData, DWORD dwSize); protected:
int m_nPort;
};

  由于这个类被封装在动态库里面,所以类名前使用了导出标志XIOCTRL_CLASS,读者在使用时完全可以去掉。类的定义被放在一个包含很多类定义的头文件中,没有单独为它写头文件,所以它的定义部分代码看上去没有上下文。

CxUdpSocket的实现如下:

CxUdpSocket::CxUdpSocket()
: m_nPort(0)
{ } CxUdpSocket::~CxUdpSocket()
{ } BOOL CxUdpSocket::Bind(int nPort)
{
Disbind(); if (m_socket == INVALID_SOCKET)
m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (m_socket == INVALID_SOCKET)
return FALSE; sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(nPort); int iRet = bind(m_socket, (SOCKADDR*)&addr, sizeof(addr));
if (iRet == SOCKET_ERROR)
{
Disbind();
DWORD dwError = WSAGetLastError();
return FALSE;
} long lEvent = FD_WRITE | FD_READ | FD_CLOSE;
SelectEvent(lEvent);
m_nPort = nPort; return TRUE;
} BOOL CxUdpSocket::IsBinded()
{
sockaddr_in saCur = {0};
int nLen = sizeof(saCur);
int iResult = getsockname(m_socket, (SOCKADDR*)&saCur, &nLen);
return (iResult != SOCKET_ERROR);
} BOOL CxUdpSocket::SendTo(LPCSTR lpszIPAddr, LPBYTE lpbtData, DWORD dwSize)
{
if (m_socket == INVALID_SOCKET)
return FALSE; sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(lpszIPAddr);
addr.sin_port = htons(m_nPort); DWORD nMaxSize = MAX_MSG_SIZE, nCount = 0, nToSend;
int iRet;
LPBYTE lpbtIterator; while (nCount != dwSize)
{
nToSend = min((dwSize - nCount), nMaxSize);
lpbtIterator = &lpbtData[nCount];
iRet = sendto(m_socket, (const char*)lpbtIterator, nToSend, 0,
(SOCKADDR*)&addr, sizeof(addr));
if (iRet > 0)
nCount += iRet;
else
break;
} return (nCount == dwSize);
} BOOL CxUdpSocket::RecvFrom(LPSTR lpszIPAddr, LPBYTE lpbtData, DWORD dwSize)
{
if (m_socket == INVALID_SOCKET)
return FALSE; sockaddr_in addrRemote = {0};
int nSize = sizeof(addrRemote);
DWORD nMaxSize = MAX_MSG_SIZE;
DWORD nCount = 0;
DWORD nToReceive;
int iRet;
LPBYTE lpbtIterator; while (nCount != dwSize)
{
nToReceive = min((dwSize - nCount), nMaxSize);
lpbtIterator = &lpbtData[nCount];
iRet = recvfrom(m_socket, (char*)lpbtIterator, nToReceive, 0,
(SOCKADDR*)&addrRemote, &nSize);
if (iRet > 0)
nCount += iRet;
else
break;
} strcpy(lpszIPAddr, inet_ntoa(addrRemote.sin_addr));
return (nCount == dwSize);
} BOOL CxUdpSocket::Disbind()
{
if (m_socket == INVALID_SOCKET)
return TRUE; int nRet = closesocket(m_socket);
if (nRet == SOCKET_ERROR)
return FALSE; m_socket = INVALID_SOCKET;
m_nPort = 0;
return TRUE;
}

  类的实现被放在一个包含很多类实现的CPP文件中,没有单独为它写CPP文件,所以它的实现部分代码看上去没有上下文(比如头文件包含、宏定义等等)。MAX_MSG_SIZE是一个定义为1024的宏,来自对另一个头文件的引用(将来的文章会向大家介绍)。这个类的实现部分的代码不多,总共120多行。实现了(解)绑定地址与端口、发送接收数据以及侦听接收数据的功能(仅以消息响应的方式通知上层程序处理接收数据)。

  我写的很多实用类都非常简洁,一般都没有注释,有也是中英文混搭两句,大家习惯就好。To be continued...

 
 

C++套接字类CxUdpSocket的设计的更多相关文章

  1. 谢欣伦 - OpenDev原创教程 - 无连接套接字类CxUdpSocket

    这是一个精练的无连接套接字类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. CxUdpSocket的使用如下(以某个叫做CSomeC ...

  2. 谢欣伦 - OpenDev原创教程 - 服务端套接字类CxServerSocket

    这是一个精练的服务端套接字类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. CxServerSocket的使用如下(以某个叫做CSo ...

  3. 谢欣伦 - OpenDev原创教程 - 客户端套接字类CxClientSocket

    这是一个精练的客户端套接字类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. CxClientSocket的使用如下(以某个叫做CSo ...

  4. 服务端套接字类CxServerSocket的使用

    服务端套接字类CxServerSocket的使用 这是一个精练的服务端套接字类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣能),个人习惯而已,如有雷同,纯属巧合. CxS ...

  5. think in java 读书笔记 2 —— 套接字

    目录 think in java 读书笔记 1 ——移位 think in java 读书笔记 2 —— 套接字 think in java 读书笔记 3 —— 数据报 概要 1. 套接字基本知识 2 ...

  6. Linux网络编程——原始套接字编程

    原始套接字编程和之前的 UDP 编程差不多,无非就是创建一个套接字后,通过这个套接字接收数据或者发送数据.区别在于,原始套接字可以自行组装数据包(伪装本地 IP,本地 MAC),可以接收本机网卡上所有 ...

  7. Linux网络编程:原始套接字简介

    Linux网络编程:原始套接字编程 一.原始套接字用途 通常情况下程序员接所接触到的套接字(Socket)为两类: 流式套接字(SOCK_STREAM):一种面向连接的Socket,针对于面向连接的T ...

  8. C#利用 HttpWebRequest 类发送post请求,出现“套接字(协议/网络地址/端口)只允许使用一次”问题

    声明:问题虽然已经被解决,但是并没有明白具体原理,欢迎大佬补充. 最近网站出现一个问题,在C#里面使用  HttpWebRequest 类去发送post请求,偶尔 会出现 “套接字(协议/网络地址/端 ...

  9. 03、Windows Phone 套接字(Socket)实战之WP客户端设计

    因为 PC 端和 WP 端进行通信时,采用的自定义的协议,所以也需要定义 DataType 类来判断 通信数据的类型,并且把数据的描述信息(head) 和数据的实际内容(body)进行拼接和反转,所以 ...

随机推荐

  1. 关于webbrowser控件自动登陆的问题

    原文:关于webbrowser控件自动登陆的问题 楼主dtb(陈少)2004-03-04 22:16:55 在 VB / 网络编程 提问 请问怎么用webbrowser自动登陆www.jp168.co ...

  2. MVC模型部分验证

    ASP.NET MVC模型部分验证 在很多情况下,我们为了代码的复用可能会存在ViewModel共用的情形.比方说,web应用中常常会遇到的一个需求就是用户找回密码的功能.用户首先要验证通过验证邮箱( ...

  3. 使用SQL Server Driver for PHP解决PHP连接MSSQL乱码的问题

    原文 使用SQL Server Driver for PHP解决PHP连接MSSQL乱码的问题 最近帮客户写了一个.net商城网站的发布接口,大家都知道.net一般都使用MSSQL数据库,但鱼丸不会. ...

  4. phpstorm集成phpunit

    1.下载phpunit.phar,将该文件放到某个工程中 2.File > Settings > Languages & Frameworks > PHP > PHPU ...

  5. 解决Postman发送post数据但是Node.js中req.body接收不到数据的问题[已解决]

    之前编写后台接口,测试数据都是使用的Postman,相当的方便,之前也一直使用get方法,编写Node.js一直没有问题,但是由于要编写一个注册/登陆的功能,所以发送的post数据,后台的逻辑已经编写 ...

  6. postal邮件发送(二):Email headers,附件,图片介绍

    接上篇 http://www.cnblogs.com/mybky/p/5690567.html 1.邮件headers 除此之外,还有Reply-To,用于回复邮箱 2.邮件带有图片 邮件发送图片,p ...

  7. Unity 3.5

    ASP.NET Web Forms 的 DI 應用範例 跟 ASP.NET MVC 与 Web API 比起来,在 Web Forms 应用程式中使用 Dependency Injection 要来的 ...

  8. Javascript Array API

    JS数组对象提供了很多API方法,由于前段时间要用到某一些方法,但是突然一时又想不起来该怎么用了,上网找有很多资料都不全,所以就自己整理了一篇,完全是自己写的的JS,只是复制到这里来了 ,要用到的朋友 ...

  9. .NET MVC4 实训记录之四(Unit of work + Repository)

    今日后开启进阶模式! 谈到MVC与EntityFramework,则不得不说一说事务与仓储(Unit of work + Repository). 仓储(Repository):领域对象集合.用于操作 ...

  10. Js 数组(一):基础应用

    (一) Js 数据类型 分为基本数据类型以及引用类型 基本数据类型有 null,undefined,Boolen,Number,String,还有一种复杂数据类型 Object. var var1 = ...