C++之基于Winsock2封装UDPServer与UDPClient

news2025/7/12 7:54:50

文章目录

    • Socket过程
    • UDPServer.h
    • UDPServer.cpp
    • UDPClient.h
    • UDPClient.cpp
    • main.cpp
    • CMakeLists.txt
    • 测试截图

Socket过程

  • UDPServer

  • UDPClient

UDPServer.h

#ifndef UDPSERVER_H_INCLUDED
#define UDPSERVER_H_INCLUDED

#include <iostream>
#include <string>
#include <Winsock2.h>

class UDPServer
{
private:
    WORD sockVersion;
    WSADATA wsaData;
    SOCKET udpSocket;
    sockaddr_in localAddr;
    sockaddr_in remoteAddr; // Client
    const int MSG_SIZE = 1024;

public:
    UDPServer();
    ~UDPServer();
    void Bind(u_short port);
    void Receive();
    bool Send(std::string message);
};

#endif // UDPSERVER_H_INCLUDED

UDPServer.cpp

#include "UDPServer.h"

UDPServer::UDPServer()
{
    sockVersion = MAKEWORD(2, 2);
    WSAStartup(sockVersion, &wsaData);
    udpSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
}

UDPServer::~UDPServer()
{
    closesocket(udpSocket);
    WSACleanup();
}

void UDPServer::Bind(u_short port)
{
    localAddr.sin_family = AF_INET;
    localAddr.sin_port = htons(port);
    // localAddr.sin_addr.S_un.S_addr = INADDR_ANY; // 0.0.0.0
    localAddr.sin_addr.S_un.S_addr = inet_addr("0.0.0.0");
    bind(udpSocket, (const sockaddr *)&localAddr, sizeof(localAddr));
}

void UDPServer::Receive()
{
    while (true)
    {
        char recvBuffer[MSG_SIZE];
        int localAddrSize = sizeof(localAddr);
        int lenRemoteAddr = sizeof(remoteAddr);
        int len = recvfrom(udpSocket, recvBuffer, MSG_SIZE, 0, (SOCKADDR *)&remoteAddr, &lenRemoteAddr);
        if (len > 0)
        {
            recvBuffer[len] = '\0';
            std::cout << "[" << inet_ntoa(remoteAddr.sin_addr) << ":" << remoteAddr.sin_port << "] -> " << recvBuffer << std::endl;
        }
    }
}

bool UDPServer::Send(std::string message)
{
    int ret = sendto(udpSocket, message.c_str(), message.length(), 0, (sockaddr *)&remoteAddr, sizeof(remoteAddr));
    if (ret == SOCKET_ERROR)
    {
        return false;
    }
    else
    {
        return true;
    }
}

UDPClient.h

#ifndef UDPCLIENT_H_INCLUDED
#define UDPCLIENT_H_INCLUDED

#include <iostream>
#include <string>
#include <Winsock2.h>

class UDPClient
{
private:
    WORD sockVersion;
    WSADATA wsaData;
    SOCKET udpSocket;
    sockaddr_in localAddr;
    sockaddr_in remoteAddr; // Client
    const int MSG_SIZE = 1024;

public:
    UDPClient();
    ~UDPClient();
    void Bind(std::string ip, u_short port);
    void Receive();
    bool Send(std::string message);
};

#endif // UDPCLIENT_H_INCLUDED

UDPClient.cpp

#include "UDPClient.h"

UDPClient::UDPClient()
{
    sockVersion = MAKEWORD(2, 2);
    WSAStartup(sockVersion, &wsaData);
    udpSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
}

UDPClient::~UDPClient()
{
    closesocket(udpSocket);
    WSACleanup();
}

void UDPClient::Bind(std::string ip, u_short port)
{
    localAddr.sin_family = AF_INET;
    localAddr.sin_port = htons(port);
    localAddr.sin_addr.S_un.S_addr = INADDR_ANY; // 0.0.0.0
    remoteAddr = localAddr;
    remoteAddr.sin_addr.S_un.S_addr = inet_addr(ip.c_str());
    bind(udpSocket, (const sockaddr *)&localAddr, sizeof(localAddr));
    Send("Hello");
}

void UDPClient::Receive()
{
    while (true)
    {
        char recvBuffer[MSG_SIZE];
        int localAddrSize = sizeof(localAddr);
        int lenRemoteAddr = sizeof(remoteAddr);
        int len = recvfrom(udpSocket, recvBuffer, MSG_SIZE, 0, (SOCKADDR *)&remoteAddr, &lenRemoteAddr);
        if (len > 0)
        {
            recvBuffer[len] = '\0';
            std::cout << "[" << inet_ntoa(remoteAddr.sin_addr) << ":" << remoteAddr.sin_port << "] -> " << recvBuffer << std::endl;
        }
    }
}

bool UDPClient::Send(std::string message)
{
    int ret = sendto(udpSocket, message.c_str(), message.length(), 0, (sockaddr *)&remoteAddr, sizeof(remoteAddr));
    if (ret == SOCKET_ERROR)
    {
        return false;
    }
    else
    {
        return true;
    }
}

main.cpp

#include <iostream>
#include <thread>
#include <string>

#include "UDPClient.h"
#include "UDPServer.h"

int main()
{
    std::cout << "[0] -> UDPServer"
              << "\n"
              << "[1] -> UDPClient" << std::endl;
    u_int flag = 2;
    std::cin >> flag;

    switch (flag)
    {
    case 0:
    {
        std::cout << "[UDPServer] -> Start" << std::endl;
        UDPServer udpServer;
        udpServer.Bind(6789);
        std::thread recvThread(&UDPServer::Receive, &udpServer);

        // 主线程
        while (true)
        {
            std::cout << "\n[Input] -> ";
            std::string msg;
            std::cin >> msg;
            if (udpServer.Send(msg))
            {
                std::cout << "[UDPServer] -> " << msg << std::endl;
            }
            else
            {
                std::cout << "[ErrorCode] -> " << GetLastError() << std::endl;
            }
        }

        // 等待线程结束
        recvThread.join();

        std::cout << "[UDPServer] -> Stop" << std::endl;
        break;
    }
    case 1:
    {
        std::cout << "[UDPClient] -> Start" << std::endl;
        UDPClient udpClient;
        udpClient.Bind("127.0.0.1", 6789);
        std::thread recvThread(&UDPClient::Receive, &udpClient);

        // 主线程
        while (true)
        {
            std::cout << "\n[Input] -> ";
            std::string msg;
            std::cin >> msg;
            if (udpClient.Send(msg))
            {
                std::cout << "[UDPClient] -> " << msg << std::endl;
            }
            else
            {
                std::cout << "[ErrorCode] -> " << GetLastError() << std::endl;
            }
        }

        // 等待线程结束
        recvThread.join();

        std::cout << "[UDPClient] -> Stop" << std::endl;
        break;
    }

    default:
        break;
    }

    system("pause");
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.0.0)
project(UDPProtocol VERSION 0.1.0 LANGUAGES CXX)

add_executable(${PROJECT_NAME} 
    UDPClient.cpp
    UDPServer.cpp
    main.cpp)

if(WIN32)
    target_link_libraries(${PROJECT_NAME} PRIVATE ws2_32)
endif()

测试截图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1103885.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

漫谈下一代防火墙与Web应用防火墙的区别

如今&#xff0c;Web应用程序变得越来越复杂&#xff0c;更是黑客非常感兴趣的目标。在谈到网络安全的话题时&#xff0c;我们总会讨论下一代防火墙与Web应用防火墙的区别。当已经拥有下一代防火墙&#xff08;NGFW&#xff09;时&#xff0c;为什么需要Web应用程序防火墙&…

靶机 Raven2 / UDF 提权

Raven2 信息搜集 存活检测 详细扫描 后台扫描 dirsearch -u http://10.4.7.135 -x 403 # 过滤状态码为 403 的后台页面Webshell 漏洞发现 访问扫描出的后台页面 /vendor 页面 发现网站使用了 PHPMailer PHPMailer是一个用于发送电子邮件的PHP库。它提供了一个简单而灵活的…

PFL-MoE:基于混合专家的个性联邦学习

文章链接&#xff1a;PFL-MoE: Personalized Federated Learning Based on Mixture of Experts 发表会议&#xff1a;APWeb-WAIM 2021&#xff08;CCF-C&#xff09; 目录 1.背景介绍联邦学习non-IIDPFL 2.内容摘要关键技术A.PFL-MoEB.PFL-MFC.PFL-MFE 实验结果 3.文章总结 1.…

QT 绘制文字轮廓

最近在做文字绘制&#xff0c;需要用到绘制文字轮廓&#xff0c;发现QT里面有自己的解决方案&#xff0c;分享出来&#xff1b; 具体贴代码 #include "mainwindow.h" #include "ui_mainwindow.h" #include <QPainter>MainWindow::MainWindow(QWidg…

Qt (QInputDialog 、QMessageBox、QMessageBox)对话框实战

目录 一、QInputDialog 类(输入对话框) 二、QMessageBox 类(消息框) 三、QMessageBox 类(自定义消息框) 一、QInputDialog 类(输入对话框) QInputDialog 是一个提供输入对话框的 Qt 类。它允许用户输入文本&#xff0c;并提供给用户选择可用选项的选项列表。QInputDialog 可…

Elasticsearch使用——结合MybatisPlus使用ES es和MySQL数据一致性 结合RabbitMQ实现解耦

前言 本篇博客是一篇elasticsearch的使用案例&#xff0c;包括结合MybatisPlus使用ES&#xff0c;如何保证MySQL和es的数据一致性&#xff0c;另外使用了RabbitMQ进行解耦&#xff0c;自定义了发消息的方法。 其他相关的Elasticsearch的文章列表如下&#xff1a; Elasticsear…

ES6 Symbol 数据结构

1. Symbol概念以及引入原因 ES6 引入了的一种新的原始数据类型Symbol&#xff0c;表示独一无二的值。它是 JavaScript 语言的第七种数据类型&#xff0c;前六种是&#xff1a;undefined、null、布尔值&#xff08;Boolean&#xff09;、字符串&#xff08;String&#xff09;、…

政务OA协同办公系统:数字化工具助力政府服务升级

在当今数字化时代&#xff0c;政务OA协同办公系统已经成为政府服务升级的重要工具。通过引入数字化技术&#xff0c;政务OA协同办公系统可以实现高效的信息传递、流程优化以及资源整合&#xff0c;进一步提升政府服务的质量和效率。本文将探讨政务OA协同办公系统的优势及其在数…

【UE5 Cesium】19-Cesium for Unreal 建立飞行跟踪器(4)

遗留问题 在上一篇博客中&#xff08;【UE5 Cesium】18-Cesium for Unreal 建立飞行跟踪器&#xff08;3&#xff09;&#xff09;&#xff0c;我们实现了飞机变速飞行的功能&#xff0c;但是还存在两个问题&#xff0c;分别是&#xff1a; &#xff08;1&#xff09;由于UE的…

三维地图开发三维地图服务器

三维地图开发三维地图服务器 发布时间&#xff1a;2020-03-03 版权&#xff1a; 搭建离线地图服务主要是两个步骤&#xff1a;一是&#xff1a;下载离线地图服务需要的地图数据&#xff1b;二是&#xff1a;将下载的离线地图数据发布成地图服务&#xff1b;只有做好这两步&…

【java零基础入门到就业】第二天:jdk的下载安装和第一个HelloWorld程序

1、java内容概述 java前半部分学习内容主要如下&#xff1a; 1、Java基础语法2、面向对象3、API4、字符串5、集合6、拼图游戏 1.1、 java基础语法 java基础语法主要包括以下内容&#xff1a; Java入门小概念Idea和运算符判断和循环方法数组课后练习题 Java是什么&#xf…

Qt基础 QPieSeries饼状图

目录 1.简单例子 2. 稍微复杂点 QPieSeries Class&#xff1a;饼状图数据 QChart 管理图表系列、图例和轴的图形表示 QChartView 可以显示图表的独立小部件 QPieSeries 在饼图中显示数据 QPieSlice 表示饼图系列中的单个切片&#xff08;其实就是标签&#xff09; 1…

鸿蒙应用开发之HTTP数据请求

一、概述 日常生活中我们使用应用程序看新闻、发送消息等&#xff0c;都需要连接到互联网&#xff0c;从服务端获取数据。例如&#xff0c;新闻应用可以从新闻服务器中获取最新的热点新闻&#xff0c;从而给用户打造更加丰富、更加实用的体验。 那么要实现这样一种能实时从服务…

Python突破浏览器TLS/JA3 指纹

JA3 是一种创建 SSL/TLS 客户端指纹的方法&#xff0c;一般一个网站的证书是不变的&#xff0c;所以浏览器指纹也是稳定的&#xff0c;能区分不同的客户端。 requests库 Python requests库请求一个带JA3指纹网站的结果&#xff1a; import requestsheaders {authority: tls…

P2251 质量检测

题目&#xff1a; P2251 质量检测 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 代码&#xff1a; #include<iostream> #include<cstdio> #include<deque> #include<vector> typedef long long ll; const ll N 1e7; using namespace std;int main…

nocos配置中心使用教程(NACOS 1.X版本)

1.下载和安装 进入到官网下载就好了 解压 启动 2.新建cloudalibaba-config-nacos-client3377 2.1 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://w…

【LeetCode刷题(数据结构与算法)】:链表中的两数相加

给你两个非空的链表&#xff0c;表示两个非负的整数 它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储一位数字 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表 你可以假设除了数字 0 之外&#xff0c;这两个数都不会以 0 开头 示例1&…

数据库如何储存和管理数据的?

文章目录 磁盘IO数据的存储特别的 前言:众所周知,数据库就是一个将各类数据,以表格的形式存储的,但是看似如此简单的功能它是真的简单吗?我们和直接使用简单的Excel建立的表格有区别吗?如果有在哪里? PS&#xff1a;本文以常用的MySQL为例 磁盘IO 在不考虑缓存等机制&#…

【Tent-SSA-BP】基于Tent混沌映射改进的麻雀算法优化BP神经网络回归预测研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

站内全文搜索,怎样能更好找到自己想要的信息?

对于博客或者文档&#xff0c;站内全文搜索是非常重要的功能。现在有许多网站生成器工具可供选择&#xff0c;无论是静态的、带有完整后台的&#xff0c;还是基于低代码或无代码的。但是如今网站往往拥有大量的内容和信息。为了能够快速有效找到所需的信息&#xff0c;无论是通…