利用windows的SOCKET编写自己的UDP通信类
程序员文章站
2022-06-29 18:54:40
...
VS2015
win32控制台应用程序
我建的类名为MyUdpSocket,
MyUdpSocket.h头文件如下:
#pragma once
#include <string>
#include <vector>
#include <winsock2.h>
#include <iostream>
using namespace std;
class MyUdpSocket
{
public:
MyUdpSocket();
~MyUdpSocket();
bool Initial(int nlocalPort, string strLocalIP, int nRemotePort, string strRemoteIP, bool bBlockMode = true);
bool RecvData(std::vector<char>& vReplay);
bool SendData(std::vector<char>& vSendData);
public:
SOCKET m_pcSocket;
sockaddr_in m_pcAddr;
sockaddr_in m_deviceCmdAddr;
};
MyUdpSocket.h源文件如下:
#include "stdafx.h"
#include "MyUdpSocket.h"
MyUdpSocket::MyUdpSocket()
{
}
MyUdpSocket::~MyUdpSocket()
{
}
bool MyUdpSocket::Initial(int nlocalPort, string strLocalIP, int nRemotePort, string strRemoteIP, bool bBlockMode)
{
WSADATA wsaData0;
if (0 == WSAStartup(MAKEWORD(2, 2), &wsaData0))
{
m_pcSocket = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
unsigned long iMode = 0;
if (!bBlockMode)
{
iMode = 1;
}
int nResult = ::ioctlsocket(m_pcSocket, FIONBIO, &iMode);//FIONBIO:允许或禁止套接口s的非阻塞模式。iMode:允许非阻塞模式则非零,如禁止非阻塞模式则为零
if (m_pcSocket == INVALID_SOCKET)
{
printf("INVALID_SOCKET!");
}
m_pcAddr.sin_family = AF_INET;
m_pcAddr.sin_port = ::htons((UINT)(nlocalPort));
//m_pcAddr.sin_addr.S_un.S_addr = ::htonl(INADDR_ANY);
m_pcAddr.sin_addr.S_un.S_addr = inet_addr(strLocalIP.c_str());
//绑定本地网口时,指定strLocalIP是为了 :1.从该网口接数据 2.发数据的时候从该网口出去(如果电脑有两个网口的话就必须绑定本地网口,如果只有一个网口的话可以用::htonl(INADDR_ANY)表示绑定任意网口)
int nRet = ::bind(m_pcSocket, (sockaddr*)&m_pcAddr, sizeof(sockaddr));
if (nRet != 0)
{
printf("%s Socket bind failed!", strLocalIP);
return false;
}
m_deviceCmdAddr.sin_family = AF_INET;
m_deviceCmdAddr.sin_port = ::htons(nRemotePort);
m_deviceCmdAddr.sin_addr.S_un.S_addr = inet_addr(strRemoteIP.c_str());
}
return true;
}
bool MyUdpSocket::RecvData(std::vector<char>& vReplay)
{
sockaddr_in deviceAddr;
int nAddrLen = sizeof(deviceAddr);
int nDataLen = vReplay.size();
int nRet = ::recvfrom(m_pcSocket, (char*)&vReplay[0], nDataLen, 0, (SOCKADDR*)&deviceAddr, &nAddrLen);
//int nRet = ::recvfrom(m_pcSocket, (char*)&vReplay[0], 568, 0, (SOCKADDR*)&deviceAddr, &nAddrLen);
if (nRet > 0)
{
return true;
}
else
{
return false;
}
}
bool MyUdpSocket::SendData(std::vector<char>& vSendData)
{
int nSendDataLen = vSendData.size();
int nResult = sendto(m_pcSocket, (char*)&vSendData[0], nSendDataLen, 0, (SOCKADDR*)&m_deviceCmdAddr, sizeof(SOCKADDR));
if (nResult == nSendDataLen)
{
return true;
}
else
{
return false;
}
}
注意:在stdafx.h文件中需要添加如下代码:
#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
// 关闭对某些常见但经常可放心忽略的警告消息的隐藏
用法如下:
首先在头文件中包含该MyUdpSocket.h
#include "MyUdpSocket.h"
然后定义类对象,并调用初始化函数,设置本地及远端的端口和IP
MyUdpSocket *m_socketRecvCommand = new MyUdpSocket;
m_socketRecvCommand->Initial(1111, "192.168.5.11", 1111, "192.168.5.10");//(本地端口,本地IP,远端设备端口,远端设备IP)
注意:该socket默认是阻塞式的,若想设置成非阻塞式则Initial时候需增加一个bool变量,如下:
m_socketRecvCommand->Initial(1111, "192.168.5.11", 1111, "192.168.5.10",false);
接数据:
std::vector<char> vRecvCommand(512, 0);//定义一个512字节容量的vector容器vRecvCommand
m_socketRecvCommand->RecvData(vRecvCommand)//调用接收函数,若接到数据则数据存放在vRecvCommand中
发数据:
vector<char> vSendData(nPacketLen, 0);
memcpy(&vSendData[0], &m_packetReCommand, nPacketLen);//m_packetReCommand是一个存放好需要发送数据的结构体
m_socketRecvCommand->SendData(vSendData);
上一篇: 下载node,npm报错
下一篇: Windows 运行中的命令