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. 经典HTML5小游戏 支持各种浏览器 (围住神经猫)

    源码地址: http://files.cnblogs.com/files/liujing379069296/MyCat.rar 插件地址:http://files.cnblogs.com/files/ ...

  2. EF 事物

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...

  3. MySQL 升级方法指南大全

    原文:MySQL 升级方法指南大全 通常,从一个发布版本升级到另一个版本时,我们建议按照顺序来升级版本.例如,想要升级 MySQL 3.23 时,先升级到 MySQL 4.0,而不是直接升级到 MyS ...

  4. 被FusionCharts V3.4抛弃的东西

    从FusionCharts Suite XT V3.4開始,FusionCharts产品家族放弃了Flash,发展成为一个纯JavaScript的图表组件.前面我们介绍了怎样升级到V3.4,接下来让我 ...

  5. Hadoop群集设置

    Hadoop群集设置 近期特别看了Hadoop的资料.感觉特别好,整理一下发在自己的博客上,希望对想了解集群的网友有所帮助. 參考资料:http://hadoop.apache.org/docs/r1 ...

  6. JSR303 Bean Validation 技术规范特性概述

    概述 Bean Validation 规范 Bean 是 Java Bean 的缩写,在 Java 分层架构的实际应用中,从表示层到持久化层,每一层都需要对 Java Bean 进行业务符合性验证,如 ...

  7. inux平台的C与C++

    课堂里学不到的C与C++那些事(一) 首先,声明一下这是一个系列的文章.至于整个系列有多少篇,笔者也不知道,不知道有多少篇,也不知道多久会更新一篇.反正只有一个原则,写出来的文 章能见得人才会公布出来 ...

  8. 移动应用跨平台框架江湖将现终结者?速来参拜来自Facebook的React Native

    React Native使用初探 February 06 2015 Facebook让所有React Conf的参与人员都可以初尝React Native的源码---一个编写原生移动应用的方法.该方法 ...

  9. 轻量级IOC框架Guice

    java轻量级IOC框架Guice Guice是由Google大牛Bob lee开发的一款绝对轻量级的java IoC容器.其优势在于: 速度快,号称比spring快100倍. 无外部配置(如需要使用 ...

  10. QT中出现“无法解析的外部符号”错误

    串口中我要把奇偶校验等enum数据对应写到一个ComboBox中去,所以需要在我的Settings类中加入一个函数用来转换. 这里,我首先在settings.h的class Settings中加上对该 ...