LwUdpSocket类 Win32 api Udp Scoket的封装
众所周知, win32 api 有"神奇"之效, 只要将它们样拼积木一样堆在一起,就能实现很多很酷的东西, 但是它的数量太多, 仅微软文档开放出来足足有三千多个并且参数类型各种宏定义, 使用时出了问题时常让我们摸不头脑, 查msdn也是很消耗时间, 所以要将这些 Win Api 分门别类 的封装起来, 以后方便使用. 当然做简单的封装就可以了, 不需要样mfc或者是Qt那样
封装理论上成员都应该是私有的, 让类的外部无法直接访问到其成员, 需要通过开放接口访问 (当然用点手段还是能访问的),所以我将三个成员定义私有的
[C++] 纯文本查看 复制代码 private:
SOCKET _socket; // 本地套接字
const char* _ip; // ip地址
int _port; // 端口号
曾经我是这么定义SOCKET* _socket, 当初我以为它是个结构体, 在c++中如果将结构体直接赋值给另一个变量, 系统会将这个结构体的所占内存空间拷贝过去,
影响程序运行速度, 所以我将其定义成指针, 深究之下发现, 它居然只是个unsigned int, 只是整型就没必须定义成指针了, 只是4个字节而已
[C++] 纯文本查看 复制代码 SOCKET 是 UINT_PTR的别名
而UINT_PTR是unsigned int的别名
之后按照正常创建udp socket 流程封装了几个方法, 网络环增初始化以及socket 创建都在构造函数中, 当然了socket的关闭以及各种清除都在析构函数中:
[C++] 纯文本查看 复制代码 LwUdpSocket(const char *ip, unsigned int port);
~LwUdpSocket();
SOCKET GetSocket(); // 获取socket句柄
bool Bind(); // 绑定地址
int Send(const char *ip, unsigned int port, const char *buffer, int len); // 发送信息, 如果成功, 则返回发送的字节数,失败则返回SOCKET_ERROR
// 接收消息, 返回-1表示接收失败, 注意如果你的buff长度是512, 那么len就不能大于512
// buff只能在堆中申请内存, 栈中申请这个封装的方法会失败
int Recv(char* buffer, int len, sockaddr_in* sockaddr);
完整的代码
LwUdpSocket.h
[C++] 纯文本查看 复制代码 #ifndef __LW_UDP_SOCKET_H__
#define __LW_UDP_SOCKET_H__
#include "LwNetworkInterface.h" // 需要这个类的方法辅助
// udp socket的封装
class LwUdpSocket
{
private:
SOCKET _socket; // 本地套接字
const char* _ip; // ip地址
int _port; // 端口号
public:
LwUdpSocket(const char *ip, unsigned int port);
~LwUdpSocket();
SOCKET GetSocket(); // 获取socket句柄
bool Bind(); // 绑定地址
int Send(const char *ip, unsigned int port, const char *buffer, int len); // 发送信息, 如果成功, 则返回发送的字节数,失败则返回SOCKET_ERROR
// 接收消息, 返回-1表示接收失败, 注意如果你的buff长度是512, 那么len就不能大于512
// buff只能在堆中申请内存, 栈中申请这个封装的方法会失败
int Recv(char* buffer, int len, sockaddr_in* sockaddr);
};
#endif // !__LW_UDP_SOCKET_H__
LwUdpSocket.cpp
[C++] 纯文本查看 复制代码 #include "LwUdpSocket.h"
LwUdpSocket::LwUdpSocket(const char *ip, unsigned int port)
{
// 初始化网络环境
LwNetworkInterface::InitWinsock();
this->_ip = ip;
this->_port = port;
this->_socket = NULL;
this->_socket = socket(AF_INET, SOCK_DGRAM, 0);
}
LwUdpSocket::~LwUdpSocket()
{
if (this->_socket != NULL)
{
closesocket(this->_socket);
}
// 清除网络环境
LwNetworkInterface::ClearWinsock();
}
SOCKET LwUdpSocket::GetSocket()
{
return this->_socket;
}
bool LwUdpSocket::Bind()
{
sockaddr_in address = LwNetworkInterface::CreateSocketAddr(this->_ip, this->_port);
return bind(this->_socket, (sockaddr *)&address, sizeof(address)) == 0;
}
int LwUdpSocket::Send(const char *ip, unsigned int port, const char *buffer, int len)
{
sockaddr_in sendAddress = LwNetworkInterface::CreateSocketAddr(ip, port);
return sendto(this->_socket, buffer, len, 0, (SOCKADDR *)&sendAddress, sizeof(sendAddress));
}
int LwUdpSocket::Recv(char* buffer, int len, sockaddr_in* socketAddress)
{
int socketAddressLen = sizeof(*socketAddress);
return recvfrom(this->_socket, buffer, len, 0, (SOCKADDR *)socketAddress, &socketAddressLen);
}
如有错误, 给予指出, 非常感谢!
|