吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2309|回复: 0
收起左侧

[C&C++ 转载] LwUdpSocket Win32 api Udp Scoket的封装

[复制链接]
liv 发表于 2019-3-14 10:45
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);
}


如有错误, 给予指出, 非常感谢!


免费评分

参与人数 1吾爱币 +3 热心值 +1 收起 理由
苏紫方璇 + 3 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-16 05:49

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表