套接字编程(二)UDP服务端与客户端的通信模拟实现

news2024/12/22 19:29:43

目录

一、前言

二、UDP客户端流程信息

1、创建套接字

2、为套接字绑定地址信息(不推荐)

3、发送数据(将数据放入发送缓冲区中)

4、接收数据(从socket结构体接收缓冲区中取出数据)

5、关闭套接字

三、UDP客户端通信简单模拟实现

1、创建套接字

 2、为套接字绑定地址信息

3、发送数据

4、接收数据

 5、功能函数代码

6、主main函数

7、makefile

 四、UDP通信具体操作

1、使用ifconfig了解虚拟机ip  端口推荐选择10000以上

 2、创建俩个会话(一个用来运行服务端程序,一个用来运行客户端程序)

 3、创建服务端

 4、创建客户端

 5、客户端发送问候hello

 6、服务端收到hello  回复hi

 7、客户端收到服务端回复hi


一、前言

上一篇学习UDP服务端搭建的博文,也都是近一个周前写的博客了,当时对UDP通信展开了初步学习,清楚了网络通信的基本原理,练习掌握了关于网络通信的部分接口,应用实现了关于UDP服务端的搭建

关于服务端大致流程分为

1、创建套接字(在内核中创建一个socket结构体)

2、为套接字绑定地址信息(给创建的套接字内部描述源端IP和端口)

3、从socket结构体中的接收缓冲区中取出数据

4、将数据写入socket结构体中的发送缓冲区中

5、关闭套接字

 这一篇博文大概就是完成UDP通信的另一阶段,对于客户端通信的创建与模拟实现。

二、UDP客户端流程信息

具体流程如下:

1、创建套接字

建立内核与网卡之间的联系,在内核中创建一个socket结构体(struct socket)

2、为套接字绑定地址信息(不推荐)

一个端口只能被一个网络进程所占用,所以如果进行信息绑定那么这一个主机就只能进行这一个进程的通信了,如果在绑定信息之后又想访问其他进程信息,就会发出端口冲突,因此并不主动推荐客户端这边主动绑定地址信息。

3、发送数据(将数据放入发送缓冲区中)

    客户端与服务器的一个小的区别就是客户端总是先进行发送请求在进行接收回复,而服务端肯定是更主动的先进行数据接收,如果有主机发出请求那么才会进行请求的回应。

4、接收数据(从socket结构体接收缓冲区中取出数据)

5、关闭套接字

三、UDP客户端通信简单模拟实现

在UDP服务端通信的搭建过程中发现,所有的实现都贯穿着套接字描述符。所以将套接字描述符sockfd作为私有成员

1、创建套接字

接口中使用到的参数(地址域信息、套接字类型、协议类型)都为默认的IPV4相关的UDP参数,(AF_INET、SOCK_DGRAM、IPPROTO_UDP)


 2、为套接字绑定地址信息

需要提供ip地址参数以及端口号信息,套接字描述符作为私有成员

 下方代码对应ipv4结构体进行各项初始化


3、发送数据
 

① ssize_t sendto(int sockfd,  void *buf,  size_t dlen,

                                int flag,  struct sockaddr *peer,  socklen_t alen);

② sockfd socket返回的套接字描述符

③ buf 发送数据的起始地址

④ dlen 发送数据的长度,从buf地址开始,发送dlen长度的数据

⑤ flag 默认为0,阻塞发送(发送缓冲区满了就等着, 当发送缓冲区有空间了进行发送)

⑥ peer 对端地址信息,描述了数据要发送给谁

        描述了信息送往哪里    (这里存放的是接收方的信息)

⑦ alen 对端地址信息长度

⑧ 返回值: 成功返回实际发送数据字节长度,失败返回-1;


4、接收数据

① ssize_t recvfrom(int sockfd,  void *buf,  size_t dlen,
                                  int flag,  struct sockaddr *peer,  socklen_t  *alen);

② sockfd socket创建的套接字描述符

③ 一块地址空间, 里面用来存放我接收得到的数据

④ dlen 接收数据的字节长度

⑤ flag 默认为0,当socket接收缓冲区为空的时候进行等待,有数据了就进行接收

⑥ peer 对端地址信息,描述了接收的数据来自哪里。(这里存放的是来自发送方的地址信息)

⑦ alen  地址信息长度,里面即存放了想要接收的数据长度也存放了实际接收的数据长度

⑧ 成功返回实际接收的数据长度,失败返回-1
 


 5、功能函数代码

  1 #include<iostream>
  2 #include<string>
  3 #include<unistd.h>
  4 #include<arpa/inet.h> // 字节序转换接口头文件
  5 #include<netinet/in.h>// 地址结构类型以及协议类型头文件
  6 #include<sys/socket.h>// 套接字接口文件
  7 
  8 class UdpSocket
  9 {
 10   private:
 11     int _sockfd;
 12   public:
 13     UdpSocket():_sockfd(-1){}
 14     ~UdpSocket(){Close();}
 15     bool Sockte() // 创建套接字
 16     {
 17       _sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 18       if(_sockfd<0)
 19       {
 20         perror("socket error\n");
 21         return false;
 22       }
 23       return true;
 24     }
 25     bool Bind(const std::string& ip, uint16_t port)
 26     {
 27         struct sockaddr_in addr; // 定义一个ipv4socket结构体
 28         addr.sin_family = AF_INET;// 初始化addr结构体中的sin_family
 29         addr.sin_port = htons(port);
 30         addr.sin_addr.s_addr = inet_addr(ip.c_str());
 31         socklen_t len = sizeof(struct sockaddr_in);
 32         int ret = bind(_sockfd, (struct sockaddr*)&addr, len);
 33         if(ret<0){
 34           perror("bind error\n");
 35           return false;
 36         }                                                                                
 37         return true;
 38     }
 39     bool Recv(std::string *body, std::string *peer_ip, uint16_t *peer_port)
 40     {
 41         struct sockaddr_in peer;
 42         socklen_t len = sizeof(struct sockaddr_in);
 43         char tmp[4096]={0};
 44         ssize_t ret = recvfrom(_sockfd, tmp, 4096, 0, (struct sockaddr*)&peer, &len);
 45         if(ret<0)
 46         {
 47           perror("recv error");
 48           return false;                                                                  
 49         }
 50         *peer_ip = inet_ntoa(peer.sin_addr);
 51         *peer_port = ntohs(peer.sin_port);
 52         body->assign(tmp, ret); // 从tmp中取出ret长度数据,放入body中
 53         return true;
 54     }
 55     bool Send(const std::string &body, const std::string &peer_ip, uint16_t peer_port)
 56     {
 57         struct sockaddr_in addr;
 58         addr.sin_family = AF_INET;
 59         addr.sin_port = htons(peer_port);
 60         addr.sin_addr.s_addr = inet_addr(peer_ip.c_str());
 61         socklen_t len = sizeof(struct sockaddr_in);
 62         ssize_t ret = sendto(_sockfd, body.c_str(), body.size(), 0, (struct sockaddr*)&addr, len);
 63         if(ret < 0){
 64           perror("send error");
 65           return false;
 66         }
 67         return true;
 68     }
 69     bool Close()
 70     {
 71         if(_sockfd != -1)
 72         {
 73           close(_sockfd);
 74           _sockfd = -1;
 75         }
 76         return true;
 77     }
 78 };

6、主main函数

   81 int main(int argc, char* argv[])
   82 {
   83     if(argc != 3)
   84     {
   85       std::cout<<"usage: ./client.cpp 192.168.2.2 9000\n";                             
   86       return -1;
   87     }
   88     std::string srv_ip = argv[1];
   89     uint16_t srv_port = std::atoi(argv[2]);
   90     UdpSocket socket;
   91     // 1、创建套接字
   92     assert(socket.Sockte() == true);
   93     // 2、绑定套接字(不推荐)
   94     while(1){
   95     // 3、发送数据
   96         std::string data;
   97         std::cout<<"client say:";
   98         fflush(stdout);
   99         std::cin>>data;
  100         assert(socket.Send(data, srv_ip, srv_port) == true);
  101         
  102     // 4、接收数据
  103         data.clear();
  104         //assert(socket.Recv(&data, &srv_ip, &srv_port) == true);
  105         assert(socket.Recv(&data) == true);
  106     }
  107     socket.Close();
  108     return 0;
  109 }

7、makefile

 四、UDP通信具体操作

1、使用ifconfig了解虚拟机ip  端口推荐选择10000以上

使用ens33所标记的inet

绑定端口时,推荐给出10000以上

端口范围uint16_t 0~65535       

0~1023这些端口已经被知名服务器使用了,SSH(22号端口)、HTTP(80号端口)

 2、创建俩个会话(一个用来运行服务端程序,一个用来运行客户端程序)

 3、创建服务端

 4、创建客户端

 5、客户端发送问候hello

 6、服务端收到hello  回复hi

 7、客户端收到服务端回复hi

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

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

相关文章

机器学习基本概念及问题梳理

前言&#xff1a;整理西瓜书第一、二章中的基本概念 待办&#xff1a;第二章评估方法、性能度量及后续内容未整理 下图梳理机器学习中部分概念 模型评估与选择相关知识点&#xff1a; 错误率&#xff08;error rate, E&#xff09;&#xff1a;如果在m个样本中有a个样本分类…

WordPress安全指南:19个步骤让您的WordPress安全防线坚如磐石

谈到WordPress安全性&#xff0c;您可以采取很多措施来锁定您的网站&#xff0c;以防止黑客和漏洞影响您的电子商务网站或博客。您最不想发生的事情是一天早上醒来发现您的网站一团糟。因此&#xff0c;今天我们将分享许多技巧、策略和技术&#xff0c;您可以使用这些技巧、策略…

WEBSHELL管理工具流量特征——基础篇

前言 前一阵子帮别人做取证题目&#xff0c;有很多关于WEBSHELL的流量要分析&#xff0c;想起来还有没好好分析过于是准备写篇文章总结一下帮助大家能够快速的辨别WEBSHELL流量&#xff0c;下面我们展开文章来讲。 中国菜刀 这个应该是大家最熟悉的WEBSHELL管理工具&#xf…

NeuRay学习笔记

Neural Rays for Occlusion-aware Image-based Rendering 主页&#xff1a;https://liuyuan-pal.github.io/NeuRay/ 论文&#xff1a;https://arxiv.org/abs/2107.13421 Code&#xff1a;https://github.com/liuyuan-pal/NeuRay 效果&#xff1a; desktop摘要 We present a ne…

一文读懂 UniProt 数据库(2023 最新版)

一、UniProt 数据库介绍 Uniprot &#xff08;Universal Protein &#xff09;是包含蛋白质序列&#xff0c;功能信息&#xff0c;研究论文索引的蛋白质数据库&#xff0c;整合了包括EBI&#xff08; European Bioinformatics Institute&#xff09;&#xff0c;SIB&#xff0…

【面试题】前端最新面试题-浏览器 dom、bom篇

原文见&#xff1a;语雀&#xff08;https://www.yuque.com/deepstates/interview/fsitlt&#xff09; ● BOM ● window对象 ○ frames ■ iframe ■ 跨窗口通信 ■ 同源策略/跨域 ○ navigator ● DOM ○ DOM结构 ○ DOM操作 ○ DOM事件 ■ 表单事件 ● 浏览器渲染 ○ 进程、…

Vue组件化编程的组件通信

对于组件化编程&#xff0c;组件之间的通信技术无疑是非常重要的内容&#xff0c;需要将细节牢牢把握。 组件通信&#xff0c;就是子组件放置在父组件内之后&#xff0c;父组件如何向子组件传递参数以及子组件如何与外部组件进行互动。 这部分的知识很重要&#xff0c;需要展开…

基于Ubuntu20.04搭建OpenHarmony v3.0.6的qemu仿真环境

基于Ubuntu20.04搭建OpenHarmony v3.0.6的qemu仿真环境0. 前言1. 安装Ubuntu1.1 更换华为源1.2 安装必要工具2. 下载代码2.1 解压与目录设置3. 配置环境3.1 安装库和工具3.2 设置python版本3.3 安装编译工具hb3.4 切换dash为bash4. 编译4.1 hb构建4.2 启动qemu5. 第二种环境配置…

Java之日期与时间、JDK8新增日期类、包装类、正则表达式、Arrays类、常见算法和Lambda表达式

目录日期与时间DateSimpleDateFormatCalendar概述JDK8新增日期类概述、LocalTime /LocalDate / LocalDateTimeInstantDateTimeFormatterDuration/PeriodchronoUnit包装类正则表达式Arrays类Arrays类概述&#xff0c;常用功能演示Arrays类对于Comparator比较器的支持常见算法选择…

[论文翻译] GIKT: A Graph-based Interaction Model forKnowledge Tracing

摘要随着在线教育的快速发展&#xff0c;知识追踪&#xff08;KT&#xff09;已成为追踪学生知识状态并预测他们在新问题上的表现的基本问题。在线教育系统中的问题通常很多&#xff0c;并且总是与更少的技能相关联。然而&#xff0c;以往的文献未能将问题信息与高阶问题-技能相…

计网必会:电路交换和分组交换

电路交换和分组交换的概念和区别&#xff0c;为什么分组交换更有效&#xff1f; 电路交换&#xff1a;由于电路交换在通信之前要在通信双方之间建立一条被双方独占的物理通路&#xff08;由通信双方之间的交换设备和链路逐段连接而成&#xff09; 特点是源和目标点建立起名副其…

C语言中的void*是什么?

目录1.void *是什么2.void*的解引用3.void*类型的应用场景1.void *是什么 我们之前学过许多类型的指针变量&#xff0c;如整形指针&#xff0c;字符指针&#xff0c;甚至数组指针&#xff0c;函数指针等。 int a 10; int *pa &a;//整形指针pa接受一个整形变量a的地址但…

阻塞队列-BlockingQueue

一、BlockingQueue介绍BlockingQueue 继承了 Queue 接口&#xff0c;是队列的一种。Queue 和 BlockingQueue 都是在 Java 5 中加入的。阻塞队列&#xff08;BlockingQueue&#xff09;是一个在队列基础上又支持了两个附加操作的队列&#xff0c;常用解耦。两个附加操作:支持阻塞…

Win10 每天蓝屏多次,蓝屏代码0x3B:SYSTEM_SERVICE_EXCEPTION

环境&#xff1a; 联想E14笔记本 Win10 专业版 问题描述&#xff1a; Win10 每天发生蓝屏多次&#xff0c;蓝屏代码0x3B:SYSTEM_SERVICE_EXCEPTION 查看事件查看器&#xff0c;系统日志筛选ID1001的事件,蓝屏多次基本上都是3B这错误代码 解决方案&#xff1a; 1.禁用AMD显…

vue3 pinia 状态管理(清晰明了)

前言 最近学习cloud项目&#xff0c;前端使用到 vue3 ts 等技术&#xff0c;其中包括 pinia &#xff0c;从一脸懵到渐渐清晰过程&#xff0c;在此记录一下&#xff0c;若有不足&#xff0c;希望大佬可以指出。 中文官方文档&#xff1a;https://pinia.web3doc.top/ 一、什…

2022年海南省职业院校技能大赛“网络安全”比赛任务书

2022年海南省职业院校技能大赛“网络安全” 比赛任务书 一、竞赛时间 总计&#xff1a;360分钟 二、竞赛任务书内容 &#xff08;一&#xff09;拓扑图 &#xff08;二&#xff09;A模块基础设施设置/安全加固&#xff08;350分&#xff09; 一、项目和任务描述&#xff…

服务器怎么防勒索病毒

行业背景 随着金融行业信息化建设的飞速发展&#xff0c;金融行业信息化系统经过多年的发展建设&#xff0c;目前信息化程度已经达到了较高水平。信息技术在提高管理水平、促进业务创新、提升企业竞争力方面发挥着日益重要的作用。 需求分析 随着金融信息化的深入发展&#…

Linux调试器-gdb使用

目录 1. 背景 2. 开始使用 3. 理解 创建需要调试的代码 debug&&release 4 详细调试 list&#xff0f;l 行号 list&#xff0f;l 函数名 r或run break(b) info b(reak) d num disable breakpoints enable breakpoints n (next) s&#xff08;step&#xff09; breaktrac…

ConcurrentHashMap 的优化及其与HashTable, HashMap的区别

目录 1.优化一:减小锁粒度 2.优化二:只针对写操作加锁 3.优化三:CAS 4.优化四:扩容方式 HashMap是线程不安全的,HashTable是线程安全的,关键方法加锁了.我们更推荐的是ConcurrentHashMap ,更优化的线程安全哈希表 接下来我们总结一下ConcurrentHashMap 进行了哪些优化,比H…

Nessus 扫描log4J漏洞

系列文章 Nessus介绍与安装 Nessus Host Discovery Nessus 高级扫描 Nessus 扫描web服务 Nessus 扫描log4J漏洞 1.扫描环境搭建 1.centos7 安装装宝塔面板 2.面板里下载docker 3.进入centos检查docker是否生效 docker --version4.安装docker-compose Docker Compose是一个…