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. 微信公众平台接口,asp.net实现

    原文:微信公众平台接口,asp.net实现 我为自己的笑话网开发了一个微信公众平台的接口,在这里分享给大家,希望能对朋友们有帮助,如果有什么地方写的不好,好请大家指点! 首先是要进行认证,认证的时候, ...

  2. linux简单的数据包捕获分析

    有时我们会遇到一些问题,需要捕捉数据包分析,当手头有没有专业的抓图工具,您可以使用tcpdump相反,看看(一般版本附带这个工具) 比如,我们要分析eth0与接口192.168.7.188 这个对象I ...

  3. Object-C面向对象之实现类

    Object-C面向对象之实现类 一般涉及到面向对象都会C#,Java都不可避免的涉及到类,C#中类的后缀名是.cs,Java中是.java,Object-C中一般用两个文件描述一个类,后缀名为.h为 ...

  4. 快速构建Windows 8风格应用19-基础控件II

    原文:快速构建Windows 8风格应用19-基础控件II 本篇博文接着上篇博文<快速构建Windows 8风格应用18-基础控件I>介绍开发Windows 8风格应用中常用控件. Sli ...

  5. C# 编译器选项 /platform(指定输出平台)32位程序运行到x64平台的问题

    如果说你编译的exe运行时报错: “尝试读取或写入受保护的内存.这通常指示其他内存已损坏” 这很有可能是你是以非托管的方式错误地引用了64位的API中去. 为什么会这样? 那你就要考虑VS的编译器选项 ...

  6. 提高C#编程水平的50个要点 你掌握了多少呢?

    提高C#编程水平的50个要点,程序员都是追求极致的完美主义者,下面的这些注意点和要点,你都掌握运用了多少呢? 总是用属性(Property)来代替可访问的数据成员 在 readonly 和 const ...

  7. mcstructs-MircoCStructs用C语言实现的微型数据结构库

    以C语言的方式,我将逐步实现以下算法: 我的Github地址为:https://github.com/tfa2012/mcstructs 1 线性链表 2 环形缓冲区 3 Hash表

  8. Android Intent 三解决

    Intent的接收处理: 1.Receiver报名 这之前已经被引入 然后看看剩下的两个接收功能上面. scheduleReceiver scheduleRegisteredReceiver: sch ...

  9. 02.零成本实现WEB性能测试-基于APACHE JMETER

    书评: 1.这本是介绍性能测试工具Jmeter的书籍,维度还够,但是粒度太粗. 2.对于想快速了解JMeter的使用和工具的原件使用,还是有一定的参考价值. 3.实际上,这本书可用来快速入门,掌握和了 ...

  10. 【转】android webview设置内容的字体大小

    Enum for specifying the text size. SMALLEST is 50% SMALLER is 75% NORMAL is 100% LARGER is 150% LARG ...