原创文章,欢迎转载。转载请注明:转载自 祥的博客
原文链接:http://blog.csdn.net/humanking7/article/details/50726625
不管别人的UDP类如何方便,都不如调用WinSock的API好用,但是每次都写,很不方便,所以将其封装成自己的类,方便以后调用,而且可以根据自己的需求进行扩展。自己动手,丰衣足食。
代码预览
头文件
#ifndef _QFX_CLASS_UDP_H
#define _QFX_CLASS_UDP_H
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
//UDP Class write by Qfx 2016.2.9
//The code based on the Winsocket
//*********************************************************************************************************
//Part1.
//自定义UDP类接收和发送数据类型
//*********************************************************************************************************
//IPandPort
//该结构体用于存放IP地址和端口号
struct IPandPort
{
char IP[20];
unsigned short Port;
};
//Receive Data Pack
//用于存放接收数据,使用union是便于接收和获取对应的数据
union DataReceive
{
char Buf[128];
struct DataDetail
{
double Test0_double;
UINT8 Test1_u8;
UINT8 Test2_u8[32];
double Test3_double;
}data;
};
//Receive Data Pack
//用于打包发送数据,使用union是便于接收和获取对应的数据
union DataSend
{
char Buf[128];
struct DataDetail
{
double Test0_double;
UINT8 Test1_u8;
UINT8 Test2_u8[32];
double Test3_double;
}data;
};
//*********************************************************************************************************
//Part2.
//Class Declaration我的UDP类的声明
//*********************************************************************************************************
class QfxUDP
{
private:
WSADATA m_wsaData;
SOCKET m_HostSocket;//本机对应Socket
public:
char m_HostIP[20];//本机绑定的IP地址
unsigned short m_HostPort; //本机绑定的端口号
char m_FromIP[20];//对方的IP地址
unsigned short m_FromPort;//对方的端口号
public:
//************************************
// Method: 初始化套接字
// FullName: InitSocket
// Access: public
// Returns: BOOL [->] if success return "True", if fail return "False"
// Qualifier:
// Parameter: unsigned short Port [->] Host Port for receive
//************************************
BOOL InitSocket(unsigned short Port);
//************************************
// Method: 获取本地IP地址
// FullName: GetHostIP
// Access: public
// Returns: BOOL [->] if success return TRUE. Otherwise return FALSE
// Qualifier:
// Parameter: char * HostIP [->] Host IP
//************************************
BOOL GetHostIP(char* HostIP);
//************************************
// Method: 关闭套接字
// FullName: DeletSocket
// Access: public
// Returns: BOOL
// Qualifier:
//************************************
BOOL DeletSocket(void);
//************************************
// Method: UDP发送函数
// FullName: UDP_Send
// Access: public
// Returns: void
// Qualifier:
// Parameter: char * IP [->] 目标IP地址
// Parameter: int Port [->] 目标端口号
// Parameter: char * buf [->] 发送的数据
// Parameter: int len [->] 发送的数据长度
// Parameter: int flags [->] Indicator specifying the way in which the call is made
//************************************
void UDP_Send( char* IP, unsigned short Port, char* buf, int len, int flags = 0);
//************************************
// Method: UDP接收函数
// FullName: UDP_Rece
// Access: public
// Returns: int [->] 成功后,返回接到的数据大小
// Qualifier:
// Parameter: char * buf [->] 接收数据存储的地址
// Parameter: int len [->] 接收数据的大小
// Parameter: int flags [->] Indicator specifying the way in which the call is made
//************************************
int UDP_Rece( char* buf, int len, int flags = 0);
};
#endif
lib文件
下载地址: http://download.csdn.net/detail/humanking7/9441101
使用本UDP类
main代码
#include <iostream>
using namespace std;
//引用头文件
#include "QfxClassUDP.h"
//加载lib文件
#pragma comment(lib,"QfxClassUDP.lib")
HANDLE g_Mutex; //互斥量
QfxUDP g_UDPClass;//我的UDP类对象
IPandPort g_RemoteIPPort;//远端IP地址和端口号
DataSend mySend;//要发送的数据
DataSend myRece;// 接收的数据
DWORD WINAPI UDP_Rece_ThreadProc(LPVOID pParam);
BOOL initMain();
int main()
{
if (FALSE == initMain())
{
return 0;//失败
}
while (TRUE)
{
memset(mySend.Buf,0,sizeof(mySend.Buf));
cout<<"Input发送数据1[double类型]:";
cin>>mySend.data.Test0_double;
cout<<"Input发送数据2[char类型]:";
cin>>mySend.data.Test1_u8;
cout<<"Input发送数据3[字符串类型]:";
cin>>mySend.data.Test2_u8;
cout<<"Input发送数据4[double类型]:";
cin>>mySend.data.Test3_double;
g_UDPClass.UDP_Send( g_RemoteIPPort.IP, //远端IP
g_RemoteIPPort.Port, //远端Port
mySend.Buf, //发送数据
sizeof(mySend.Buf));//数据大小
if ('q' == mySend.data.Test1_u8)
{
cout<<"退出"<<endl;//退出机制
break;
}
}
g_UDPClass.DeletSocket();
return 0;
}
BOOL initMain()
{
int host_port;
cout<<"请输入本地端口号:";
cin>>host_port;
BOOL ret = g_UDPClass.InitSocket(host_port);
if (FALSE == ret)
{
cout<<"初始化失败!"<<endl;
return FALSE;
}
cout<<"请输入远端IP地址:";
cin>>g_RemoteIPPort.IP;
cout<<"请输入远端Port:";
cin>>g_RemoteIPPort.Port;
cout<<"-------------------\n";
cout<<"本机地址: "<<g_UDPClass.m_HostIP<<" : "<<g_UDPClass.m_HostPort<<endl;
cout<<"-------------------\n-------------------\n";
//创建互斥量
g_Mutex = CreateMutex(NULL,false, ("MyThread") );
//创建线程
HANDLE handle1 = CreateThread(NULL,0,UDP_Rece_ThreadProc,NULL,0,NULL);
CloseHandle(handle1);
return TRUE;
}
DWORD WINAPI UDP_Rece_ThreadProc(LPVOID pParam)
{
int rece_num;
memset(myRece.Buf,0,sizeof(myRece.Buf));
while (TRUE)
{
WaitForSingleObject(g_Mutex,INFINITE);//等待被唤醒
rece_num = g_UDPClass.UDP_Rece( myRece.Buf, sizeof(myRece.Buf) );
if (rece_num>0)
{
cout<<"\n==================== Receive Begain ======================="<<endl;
cout<<"From "<<g_UDPClass.m_FromIP<<":"<<g_UDPClass.m_FromPort<<" ";
cout<<"Receive: "<< rece_num <<" char, say: "<<endl;
cout<<"Test0 "<<sizeof(myRece.data.Test0_double)<<" char:"<<myRece.data.Test0_double<<endl;
cout<<"Test1 "<<sizeof(myRece.data.Test1_u8)<<" char:"<<myRece.data.Test1_u8<<endl;
cout<<"Test2 "<<sizeof(myRece.data.Test2_u8)<<" char:"<<myRece.data.Test2_u8<<endl;
cout<<"Test3 "<<sizeof(myRece.data.Test3_double)<<" char:"<<myRece.data.Test3_double<<endl;
cout<<"==================== Receive End =========================="<<endl;
}
ReleaseMutex(g_Mutex);
}
return 0;
}
下一篇文章 “用WinSock封装自己的UDP类2”下面几个内容:
- 使用共用体union的好处
- 线程的创建和用法
- 互斥量的用法