C++套接字类CxUdpSocket的设计
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的设计的更多相关文章
- 谢欣伦 - OpenDev原创教程 - 无连接套接字类CxUdpSocket
这是一个精练的无连接套接字类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. CxUdpSocket的使用如下(以某个叫做CSomeC ...
- 谢欣伦 - OpenDev原创教程 - 服务端套接字类CxServerSocket
这是一个精练的服务端套接字类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. CxServerSocket的使用如下(以某个叫做CSo ...
- 谢欣伦 - OpenDev原创教程 - 客户端套接字类CxClientSocket
这是一个精练的客户端套接字类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣伦),个人习惯而已,如有雷同,纯属巧合. CxClientSocket的使用如下(以某个叫做CSo ...
- 服务端套接字类CxServerSocket的使用
服务端套接字类CxServerSocket的使用 这是一个精练的服务端套接字类,类名.函数名和变量名均采用匈牙利命名法.小写的x代表我的姓氏首字母(谢欣能),个人习惯而已,如有雷同,纯属巧合. CxS ...
- think in java 读书笔记 2 —— 套接字
目录 think in java 读书笔记 1 ——移位 think in java 读书笔记 2 —— 套接字 think in java 读书笔记 3 —— 数据报 概要 1. 套接字基本知识 2 ...
- Linux网络编程——原始套接字编程
原始套接字编程和之前的 UDP 编程差不多,无非就是创建一个套接字后,通过这个套接字接收数据或者发送数据.区别在于,原始套接字可以自行组装数据包(伪装本地 IP,本地 MAC),可以接收本机网卡上所有 ...
- Linux网络编程:原始套接字简介
Linux网络编程:原始套接字编程 一.原始套接字用途 通常情况下程序员接所接触到的套接字(Socket)为两类: 流式套接字(SOCK_STREAM):一种面向连接的Socket,针对于面向连接的T ...
- C#利用 HttpWebRequest 类发送post请求,出现“套接字(协议/网络地址/端口)只允许使用一次”问题
声明:问题虽然已经被解决,但是并没有明白具体原理,欢迎大佬补充. 最近网站出现一个问题,在C#里面使用 HttpWebRequest 类去发送post请求,偶尔 会出现 “套接字(协议/网络地址/端 ...
- 03、Windows Phone 套接字(Socket)实战之WP客户端设计
因为 PC 端和 WP 端进行通信时,采用的自定义的协议,所以也需要定义 DataType 类来判断 通信数据的类型,并且把数据的描述信息(head) 和数据的实际内容(body)进行拼接和反转,所以 ...
随机推荐
- IOS科研IOS开发笔记学习基础知识
这篇文章是我的IOS学习笔记,他们是知识的基础,在这里,根据记录的查询后的条款. 1,UIScrollView能完毕滚动的功能. 示比例如以下: UIScrollView *tableScrollVi ...
- Java项目生成静态页面
第一次做项目需要生成静态页面,网上很多大牛对将网页生成静态页面有很多异议.说一下我的看法. 不外乎有以下因素: 1.从页面加载时间来看:静态页面不需要与数据库建立连接,尤其是访问数据量较大的页面,这种 ...
- 错 'Cannot run program "/home/uv/IDE/adt/sdk/platform-tools/adb": error=2, No such file or directory
为linux平台搭建android开发环境的人,您可能会遇到问题,如下面有: 64位置linux安装64位置eclipse和64位置jdk开场后eclipse错误后 ""Canno ...
- AngularJS html5Mode与ASP.NET MVC路由
AngularJS html5Mode与ASP.NET MVC路由共存 前言 很久之前便听说AngularJS,非常酷,最近也比较火,我也在持续关注这个技术,只是没有认真投入学习.前不久公司找我们部门 ...
- 是男人就下100层【第四层】——Crazy贪吃蛇(1)
贪吃蛇是一款非常经典的游戏,这些经典游戏给我们的童年添加了不少乐趣,今天開始我们来一步一步的在Android设备上实现一款贪吃蛇游戏,我也是第一次写这个游戏,有可能会写错,或者走弯路,可是终于希望能有 ...
- [强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!)
原文:[强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!) [强烈推荐]ORACLE PL/SQL编程详解之七: 程序包的创建与应用(聪明在于学习,天 ...
- [推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下)
原文:[推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下) [推荐]ORACLE PL/SQL编程详解之一: PL/SQL 程序设计简介(千里之行,始于足下 ...
- ASP.Net TextBox控件只允许输入数字
原文:ASP.Net TextBox控件只允许输入数字 1.1.在Asp.Net TextBox 控件的 OnKeyPress 事件中指定输入键盘码必须为数字: <asp:TextBox ID= ...
- 高德地图教程_poi搜索和显示
通过高仿深圳的应用近期打算.UI我们已经做了,我见过APP查询界面.关闭网络也将是能够查询其指示数据被存储在数据库中,或者是第一网络,所有网站上的数据是好了.我想简单地使用查询地图提供了. 曾经是接触 ...
- 4行代码实现js模板引擎
在平时编码中,经常要做拼接字符串的工作,如把json数据用HTML展示出来,以往字符串拼接与逻辑混在在一起会让代码晦涩不堪,加大了多人协作与维护的成本.而采用前端模板机制就能很好的解决这个问题. 精妙 ...