首页 > 编程语言 >C++ - UDP通信

C++ - UDP通信

时间:2023-10-11 17:12:06浏览次数:42  
标签:SOCKADDR UDP sendBuf err 通信 C++ wsaData wVersion addrSrv

1. UDP通信流程

UDP就比较简单了,步骤比tcp要少一些。

连接过程图:

 

 

1.1 服务器

1.初始化套接字库

WORD wVersion;
WSADATA wsaData;
int err;
​
wVersion = MAKEWORD(1, 1);

2.创建套接字

SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0);

3.绑定

// SOCKADDR_IN addrSrv; 省略了定义和赋值
bind(sockSrv, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));

4.接收数据

char recvBuf[100];
recvfrom(sockSrv, recvBuf, 100, 0, (SOCKADDR *)&addrCli, &len);

5.发送数据

char sendBuf[] = "hello Client,I'm Server!\n";
sendto(sockSrv, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR *)&addrCli, len);

6.关闭

closesocket(sockSrv);
WSACleanup();

 

服务器具体实现代码:

#include <WinSock2.h>
#include <iostream>
​
#pragma comment(lib, "ws2_32.lib")
​
int main(void) {
    // 初始化套接字库
    WORD wVersion;
    WSADATA wsaData;
    int err;
​
    wVersion = MAKEWORD(1, 1);
    err = WSAStartup(wVersion, &wsaData);
    if (err != 0) {
        return err;
    }
​
    if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {
        WSACleanup();
        return -1;
    }
​
    // 创建套接字
    SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0);
​
    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6001);
​
    // 绑定到本机6001端口
    bind(sockSrv, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));
​
    // 接收请求,处理请求
    SOCKADDR_IN addrCli;
    int len = sizeof(SOCKADDR);
​
    char sendBuf[] = "hello Client,I'm Server!\n";
    char recvBuf[100];
​
    std::cout << "start UDP server with port 6001" << std::endl;
    while (1) {
        // 接收数据
        recvfrom(sockSrv, recvBuf, 100, 0, (SOCKADDR *)&addrCli, &len);
        std::cout << "Recv:" << recvBuf << std::endl;
​
        // 发送数据
        sendto(sockSrv, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR *)&addrCli, len);
        std::cout << "Send:" << sendBuf << std::endl;
    }
​    // 关闭
    closesocket(sockSrv);
    WSACleanup();
​
    return 0;
}
​

 

1.2 客户端

1.初始化套接字库

WORD wVersion;
WSADATA wsaData;
int err;
​
wVersion = MAKEWORD(1, 1);

2.创建UDP套接字

SOCKET sockCli = socket(AF_INET, SOCK_DGRAM, 0);
SOCKADDR_IN addrSrv;

3.接收数据

char recvBuf[100];
recvfrom(sockCli, recvBuf, 100, 0, (SOCKADDR *)&addrCli, &len);

4.发送数据

char sendBuf[] = "hello Client,I'm Server!\n";
sendto(sockCli, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR *)&addrSrv, len);

5.关闭

closesocket(sockSrv);
WSACleanup();

 

客户端具体实现代码:

#include <WinSock2.h>
#include <iostream>
​
#pragma comment(lib, "ws2_32.lib")
​
​
int main(void) {
​
    // 初始化套接字库
    WORD wVersion;
    WSADATA wsaData;
    int err;
​
    wVersion = MAKEWORD(1, 1);
    err = WSAStartup(wVersion, &wsaData);
    if (err != 0) {
        return err;
    }
​
    if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {
        WSACleanup();
        return -1;
    }
​
    // 创建UDP套接字
    SOCKET sockCli = socket(AF_INET, SOCK_DGRAM, 0);
    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6001);
​
    SOCKADDR_IN addrCli;
    int len = sizeof(SOCKADDR);
​
    char sendBuf[] = "hello, I'm Client!\n";
    char recvBuf[100];
​    // 发送数据
    std::cout << "send to Server: " << sendBuf << std::endl;
    sendto(sockCli, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR *)&addrSrv, len);
​    
    // 接收数据
    recvfrom(sockCli, recvBuf, 100, 0, (SOCKADDR *)&addrCli, &len);
    std::cout << "recv from: " << recvBuf << std::endl;
​
​    // 关闭
    closesocket(sockCli);
    WSACleanup();
​
    system("pause");
    return 0;
}
​

 

运行效果:

 

2. 总结

socket的具体细节用法我不太清楚,现阶段也只是熟悉TCP的一些简单操作,UDP的话也还不是太懂,不懂的是不知道在具体项目中该如何进行使用它们。

那个TCP的小项目也只是自己琢磨搞出来的,不知掉具体项目会不会这样去写!

 

 

————————————————

版权声明:本文为CSDN博主「cpp_learners」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/cpp_learner/article/details/121798854

标签:SOCKADDR,UDP,sendBuf,err,通信,C++,wsaData,wVersion,addrSrv
From: https://www.cnblogs.com/zhuchunlin/p/17757668.html

相关文章

  • C++ - 连接mysql数据库
    1.准备工作1.1把libmysql.dll和libmysql.lib文件复制到工程目录下首先,我们要找到刚刚开始下载的MySQL数据库的安装目录,打开目录,并且将libmysql.dll文件和libmysql.lib文件复制到工程目录下~我安装MySQL的路径:E:\mysql-5.7.42-winx64\lib把libmysql.dll文件和l......
  • C++ - 操作mysql数据库
    操作数据库的案例#include<stdio.h>#include<stdlib.h>#include<mysql.h>//固定不变的MYSQLmysql;//一个数据库结构体MYSQL_RES*res;//一个结果集结构体MYSQL_ROWrow;//char**二维数据,存放一条条记录voidconnect();//连接数据库voidinsert();//插入......
  • WebAssembly C++开发环境搭建
    WebAssembly开发环境搭建简介WebAssembly是一种新的编码方式,可以在现代的网络浏览器中运行-它是一种低级的类汇编语言,具有紧凑的二进制格式,可以接近原生的性能运行,并为诸如C/C++等语言提供一个编译目标,以便它们可以在Web上运行。它也被设计为可以与JavaScript共存,允许两......
  • c++编译报错解决办法
    所有的警告都被当作是错误在全局域:cc1plus:错误:unrecognizedcommandlineoption‘-Wno-unknown-warning’[-Werror]cc1plus:所有的警告都被当作是错误解决办法:去除CMakeLists.txt中的-Werror......
  • C++ - 文件读写
    5文件操作 程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放通过文件可以将数据持久化C++中对文件操作需要包含头文件==<fstream>== 文件类型分为两种:文本文件-文件以文本的ASCII码形式存储在计算机中二进制文件-文件以文本的二进制形式存储......
  • C++ - 模板
     本阶段主要针对C++泛型编程和STL技术做详细讲解,探讨C++更深层的使用1模板1.1模板的概念模板就是建立通用的模具,大大提高复用性 模板的特点:模板不可以直接使用,它只是一个框架模板的通用并不是万能的 1.2函数模板 C++另一种编程思想称为==泛型编程......
  • C++ - STL算法
    5STL-常用算法 概述:算法主要是由头文件<algorithm><functional><numeric>组成。 <algorithm>是所有STL头文件中最大的一个,范围涉及到比较、交换、查找、遍历操作、复制、修改等等<numeric>体积很小,只包括几个在序列上面进行简单数学运算的模板函数<funct......
  • C++ - 数组
    5数组5.1概述所谓数组,就是一个集合,里面存放了相同类型的数据元素特点1:数组中的每个==数据元素都是相同的数据类型==特点2:数组是由==连续的内存==位置组成的 5.2一维数组一维数组 5.2.1一维数组定义方式一维数组定义的三种方式:数据类型数组名[数组长度];......
  • C++ - 函数
    6函数6.1概述作用:将一段经常使用的代码封装起来,减少重复代码一个较大的程序,一般分为若干个程序块,每个模块实现特定的功能。6.2函数的定义函数的定义一般主要有5个步骤:1、返回值类型2、函数名3、参数表列4、函数体语句5、return表达式语法:返回值类型函数名(参数......
  • C++ - 指针
    7指针7.1指针的基本概念指针的作用:可以通过指针间接访问内存 内存编号是从0开始记录的,一般用十六进制数字表示可以利用指针变量保存地址 7.2指针变量的定义和使用指针变量定义语法:数据类型*变量名;示例:intmain(){ //1、指针的定义 inta=10;//定......