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)进行拼接和反转,所以 ...
随机推荐
- 数据库数据导出成XML文件
在数据库中,怎样把库中的数据导出XML文件, sql语句如下: SELECT * FROM 表名 FOR XML AUTO, ELEMENTS
- 用Iconv应对NodeJs对称加密技术在汉字编码与NoSQL的一些坑洞
·起因 汉字编码技术在实际应用中总是会存在这样或者那样的问题,尤其是在一些热门NoSQL方面多少会遇到挑战.比方说Cassandra字符集还不直接支持GB2312,要想存储写汉字那可真是麻烦.当然这还 ...
- EA强大的绘图工具---设计数据库表格
关于EA这个优秀的软件是从师哥哪里听来的,自己瞎点了点,感觉也没什么.近期和和智福加上一个师哥合作敲机房收费系统时,想到之前听人说EA非常强大,便随便找了找关于EA使用的帮助手冊.果然惊喜-- 如题, ...
- 删除Python UserWarning[已解决]
在使用MySQLdb包后,导入测试时发现一个警告. /usr/lib/python2.6/site-packages/setuptools-0.8-py2.6.egg/pkg_resources.py ...
- 快速构建Windows 8风格应用25-数据绑定
原文:快速构建Windows 8风格应用25-数据绑定 本篇博文主要介绍如何将UI元素与数据进行绑定.数据绑定的方向.数据更改通知.数据转换.数据绑定支持的绑定方案. 数据绑定是一种简单方式来显示数据 ...
- Python开发环境Wing IDE 5.0测试第八版发布
Wing IDE是著名的Python开发工具,是Wingware公司的主要产品.从1999年起,Wingware公司便开始专注于Python开发设计.Wing IDE在十几年的发展中,不管完善.其强大 ...
- 如何使用C API来操作UCI
https://forum.openwrt.org/viewtopic.php?pid=183335#p183335 Compiling UCI as stand alone with an exam ...
- 如果你使用上述这段12行的JavaScript代码,就可以能让firefox、chrome、safari浏览器崩溃,而且还能让iphone重启,安卓手机闪退!
<html> <body> <script> var total=""; for (var i=0;i<1000000;i ) { tot ...
- 非接触式电子音乐控制器CHIMAERA
本篇文章,我将介绍个有意思的设备. 她就是Chimaera,一个基于电磁场效应的非接触式电子音乐控制器. <弹奏Chimaera的声音> 霍尔效应传感器阵列及其周围部件组成了一个连续的2D ...
- Jqury笔记
1. --------------- -var aa = new Array(); aa.push(1); alert(aa[0]); var aa=[];也表示一个数组: ------------ ...