Linux--Socket编程UDP

前文:Socket套接字编程

UDP协议特点

  • 无连接:UDP在发送数据之前不需要建立连接,减少了开销和发送数据之前的时延。
  • 尽最大努力交付:UDP不保证可靠交付,主机不需要维持复杂的连接状态表。
  • 面向报文:UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。
  • 首部开销小:UDP的首部只有8个字节,比TCP的20个字节要短。
  • 支持多种交互通信:UDP支持一对一、一对多、多对一和多对多的交互通信。

大体思路

将通过客户端与服务端的创建,实现客户端能够与服务端进行通信;

利用Socket编程接口,实现双端互通;

UdpServer.hpp

包含一个udp服务端的类,通过一些成员函数,能够实现对应创建类对象,进行初始化和启动对应服务端;
在这里插入图片描述
对于服务器来说,只需要创建对应的端口号,IP地址这里为本地地址(已经确定)。

代码

#pragma once#include<iostream>
using namespace std;
#include"Log.hpp"
#include<string>
#include<cerrno>
#include<cstring>
#include<cstdlib>
#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include"InetAddr.hpp"
//描述错误码
enum
{SOCKET_ERROR =1,BIND_ERROR,USAGE_ERROR
};
const static int defaultfd = -1;//默认文件描述符为无
class UdpServer
{
public:UdpServer(uint16_t port):_sockfd(defaultfd),_port(port),_isrunning(false){}void InitServer(){//1.创建udp socket 套接字 _sockfd = socket(AF_INET,SOCK_DGRAM,0);if(_sockfd<0){LOG(FATAL,"socket error, %s, %d\n",strerror(errno),errno);exit(SOCKET_ERROR);}LOG(INFO,"socket create success,sockfd: %d\n",_sockfd);//2 先填充sockadd_in结构struct sockaddr_in local;bzero(&local,sizeof(local));local.sin_family=AF_INET;local.sin_port= htons(_port);//htons:将主机字节序转换为网络字节序//local.sin_addr.s_addr = inet_addr(_ip.c_str());local.sin_addr.s_addr=INADDR_ANY;//INADDR_ANY告诉套接字监听来自任何IP地址的连接。这对于服务器来说非常有用,因为服务器通常需要能够接受来自客户端网络上任何位置的连接请求。//再通过函数bind将套接字和网络信息连接起来int n= bind(_sockfd,(struct sockaddr* )&local,sizeof(local));if(n<0){LOG(FATAL,"bind error,%s, %d\n",strerror(errno),errno);exit(BIND_ERROR);}LOG(INFO,"socket bind success\n");}//通过循环不断接收客户端的数据,打印出对应的内容void Start(){_isrunning = true;while(true){char buffer[1024];struct sockaddr_in peer;socklen_t len= sizeof(peer);ssize_t n=recvfrom(_sockfd,buffer,sizeof(buffer)-1,0,(struct sockaddr* )&peer,&len);if(n>0){buffer[n] = 0;InetAddr addr(peer);//创建一个网络地址的类对象LOG(DEBUG, "get message from [%s:%d]: %s\n", addr.Ip().c_str(),addr.Port(),buffer);// 2. 我们要将server收到的数据,发回给对方,表示已接收sendto(_sockfd, buffer, strlen(buffer), 0, (struct sockaddr *)&peer, len);}}_isrunning = false;}
private:int _sockfd; //sock文件描述符uint16_t _port; //端口号bool _isrunning; //服务器是否启动
};

解释

在这里插入图片描述
利用socket函数创建socket编程接口,AF_INET表示IPv4,SOCK_DGRAM表示udp数据报套接字的;

在这里插入图片描述
INADDR_ANY: 调用bind()函数将套接字与一个特定的端口(以及可选的IP地址)绑定时,可以将IP地址设置为INADDR_ANY(其值通常为0,表示“任何地址”)。这样做的好处是,UDP服务器将能够接收来自任何网络接口的连接请求,而不仅仅是绑定时指定的那一个。

在这里插入图片描述
这样bind之后就能让IP地址与端口号和Socket编程接口联系起来,让接口 “有名有性” ;

在这里插入图片描述将接收的数据存储在buffer中,peer可以接收到发送端的地址信息;
只有n大于0,才表示接收到了具体数据;

在这里插入图片描述
将接收到的数据信息,可以经过一定的处理,然后发送回客户端,这里中间没有经过处理,只是将接收到的信息直接反馈给客户端而已;也就是将buffer中的内容发送到客户端中;

InetAddr.hpp

InetAddr类:将包含主机上一切有关地址的信息;
在这里插入图片描述

代码

#pragma once#include<iostream>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
using namespace std;class InetAddr
{
public:InetAddr(const struct sockaddr_in& addr):_addr(addr){GetAddress(&_ip,&_port);}string Ip(){return _ip;}uint16_t Port(){return _port;}~InetAddr(){}
private://通过已知的sockaddr信息获取对应的ip地址信息和端口号void GetAddress(string* ip,uint16_t* port){*port=ntohs(_addr.sin_port);*ip=inet_ntoa(_addr.sin_addr);}struct sockaddr_in _addr; //sockaddr的信息string _ip; //IP地址uint16_t _port; //端口号
};

main.cc

初始化服务端并启动服务端

#include<iostream>
#include<memory>
using namespace std;
#include"UdpServer.hpp"void Usage(string proc)
{cout<<"Usage:\n\t"<<proc<<" local_port\n"<<endl;
}//示例: ./main.cc 8888
int main(int argc,char* argv[])
{if(argc!=2){Usage(argv[0]);exit(USAGE_ERROR);}EnableScreen();//打印到屏幕uint16_t port = stoi(argv[1]); //获取对应的端口号unique_ptr<UdpServer> usvr=std::make_unique<UdpServer>(port);//智能指针usvr->InitServer(); // 初始化服务端usvr->Start(); // 启动服务端return 0;
}

在这里插入图片描述
通过智能指针的性质,创建一个指向UdpServer类对象的指针,能够在周期结束时自动回收对应的智能指针;

UdpClient.cc

作为客户端能够不断给服务端发送数据并接收对应数据,构建Socket编程接口与上面一致。

#include<iostream>
using namespace std;
#include<string>
#include<cstring>
#include<cstdlib>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>void Usage(string proc)
{cout<<"Usage:\n\t"<<proc<< " serverip serverport\n"<<endl;
}//示例: ./UdpClient.cc 127.0.0.1 8080
int main(int argc,char* argv[])
{if(argc!=3){Usage(argv[0]);exit(1);}string serverip=argv[1];//服务端ipuint16_t serverport=stoi(argv[2]);//服务端端口号//创建socketint sockfd = socket(AF_INET,SOCK_DGRAM,0);if(sockfd<0){cerr<<"socket error"<<endl;}//构建目标主机socket信息struct sockaddr_in server;memset(&server,0,sizeof(server));server.sin_family=AF_INET;server.sin_port=htons(serverport);server.sin_addr.s_addr=inet_addr(serverip.c_str());string message;while(true){cout<<"Please Enter# ";getline(cin,message);//获取输入的一行字符串,空格亦可接收,输入到message中sendto(sockfd,message.c_str(),message.size(),0,(struct sockaddr *)&server,sizeof(server));//发送给服务端struct sockaddr_in peer;socklen_t len = sizeof(peer);char buffer[1024];//接收存放数据ssize_t n = recvfrom(sockfd, buffer, sizeof(buffer)-1, 0, (struct sockaddr*)&peer, &len);//接收服务端发送数据if(n > 0){buffer[n] = 0;std::cout << "server echo# " << buffer << std::endl;}}
}

127.0.0.1

127.0.0.1 是一个特殊的IP地址,被称为回环地址(Loopback Address)。在IPv4网络中,它被用于指向本机(即运行代码的计算机)。当你尝试访问 127.0.0.1 上的某个端口时,你的操作系统会识别这是一个内部请求,并将该请求直接路由回本机上的相应服务,而不会通过网络发送到外部。

这种机制使得开发者能够在本地测试网络服务,而无需担心外部网络的影响。

验证

在这里插入图片描述
在这里插入图片描述
我们可以通过命令行netstat来进行查询对应网络接口:

netstat(网络统计)命令是Linux系统中用于显示网络连接、路由表、接口统计、伪装连接和多播成员等网络相关信息的强大工具。

在这里插入图片描述

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

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

相关文章

算法:[递归/搜索/回溯]二叉树的深搜

目录 题目一&#xff1a;计算布尔二叉树的值 题目二&#xff1a;求根节点到叶节点数字之和 题目三&#xff1a;二叉树剪枝 题目四&#xff1a;验证二叉搜索树 题目五&#xff1a;二叉搜索树中第k小的元素 题目六&#xff1a;二叉树的所有路径 题目一&#xff1a;计算布尔…

【C语言】宏定义常量加 ; 的错误

我在使用宏定义常量定义二维数组的时候&#xff0c;编译器报错&#xff1a;应输入“]”&#xff0c;如下&#xff1a; 原因是宏定义不是C语言规定的语句&#xff0c;它的结尾不加 ; 。在上图的 int mine[EASY_ROWS][EASY_COLS]; 中&#xff0c;把 EASY_ROWS 替换为了 9;2; &…

【秋招笔试题】小明的美食

解析&#xff1a;思维题。由于需要互不相同&#xff0c;每次操作取重复的值与最大值相加即可&#xff0c;这样即可保证相加后不会新增重复的值。因此统计重复值即可。 #include <iostream> #include <algorithm>using namespace std; const int maxn 1e5 5; int…

大模型算法面试题(十一)

本系列收纳各种大模型面试题及答案。 1、说一下目前主流或前沿的预训练模型&#xff0c;包括nlp&#xff08;百度ERNIE3.0&#xff0c;华为NEZHA&#xff0c;openAI gpt-3&#xff0c;nvidia MegatronLM&#xff0c;macrosoft T5&#xff09;和cv&#xff08;我只知道CLIP&…

wordpress主题Typecho仿百度响应式主题Xaink

wordpress主题Typecho仿百度响应式主题Xaink 新闻类型博客主题&#xff0c;简洁好看&#xff0c;适合资讯类、快讯类、新闻类博客建站&#xff0c;响应式设计&#xff0c;支持明亮和黑暗模式 直接下载 zip 源码->解压后移动到 Typecho 主题目录->改名为xaink->启用

内衣洗衣机和手洗哪个干净?推荐五款品质优良精品

在日常生活中&#xff0c;内衣洗衣机已成为现代家庭必备的重要家电之一。选择一款耐用、质量优秀的内衣洗衣机&#xff0c;不仅可以减少洗衣负担&#xff0c;还能提供高效的洗涤效果。然而&#xff0c;市场上众多内衣洗衣机品牌琳琅满目&#xff0c;让我们往往难以选择。那么&a…

实时捕获数据库变更

1.CDC概述 CDC 的全称是 Change Data Capture &#xff0c;在广义的概念上&#xff0c;只要能捕获数据变更的技术&#xff0c;我们都可以称为 CDC 。我们目前通常描述的CDC 技术主要面向数据库的变更&#xff0c;是一种用于捕获数据库中数据变更的技术&#xff0c;CDC 技术应用…

Linux嵌入式学习——数据结构——队列

一、概念 1&#xff09;定义 是只允许在一端进行插入操作&#xff0c;而在另一端进行删除操作的线性表 队列 是一种 先进先出&#xff08;First In First Out&#xff09; 的线性表 线性表有顺序存储和链式存储&#xff0c;栈是线性表&#xff0c;所以有这两种存储方式 同样…

【在开发小程序的时候如何排查问题】

在开发小程序的时候如何排查问题 在最近开发小程序的时候&#xff0c;经常出现本地在浏览器中调试没有问题&#xff0c;但是一发布到预发环境就出现各种个样的问题 手机兼用性问题 有时候会出现苹果&#x1f34e;手机键盘弹出&#xff0c;导致ui界面高度出现异常边界问题&#…

Arduino IDE界面和设置(基础知识)

Arduino IDE界面和设置&#xff08;基础知识&#xff09; 1-2 Arduino IDE界面和设置如何来正确选择Arduino开发板型号如何正确选择Arduino这个端口如何来保存一个Arduino程序Arduino ide 的界面功能按钮验证编译上传新建打开保存工作状态 1-2 Arduino IDE界面和设置 大家好这…

如何穿透模糊,还原图片真实面貌

目录 图像清晰化的魔法棒&#xff1a;AI如何穿透模糊&#xff0c;还原图片真实面貌 前言 论文背景 论文思路 模型介绍 复现过程 演示视频 使用方式 本文所涉及所有资源均在传知代码平台可获取。 图像清晰化的魔法棒&#xff1a;AI如何穿透模糊&#xff0c;还原图片真实面貌 在我…

全网最最实用--模型高效推理:量化基础

文章目录 一、量化基础--计算机中数的表示1. 原码&#xff08;Sign-Magnitude&#xff09;2. 反码&#xff08;Ones Complement&#xff09;3. 补码&#xff08;Twos Complement&#xff09;4. 浮点数&#xff08;Floating Point&#xff09;a.常用的浮点数标准--IEEE 754(FP32…

状态机 XState 使用

状态机 一般指的是有限状态机&#xff08;Finite State Machine&#xff0c;FSM&#xff09;&#xff0c;又可以称为有限状态自动机&#xff08;Finite State Automation&#xff0c;FSA&#xff09;&#xff0c;简称状态机&#xff0c;它是一个数学模型&#xff0c;表示有限个…

【计算机网络】数据链路层实验

一&#xff1a;实验目的 1&#xff1a;学习WireShark软件的抓包操作&#xff0c;分析捕获的以太网的MAC帧结构。 2&#xff1a;学习网络中交换机互相连接、交换机连接计算机的拓扑结构&#xff0c;理解虚拟局域网&#xff08;WLAN&#xff09;的通信机制。 3&#xff1a;学习…

cas 和 synchronized 优化过程

cas 什么是CAS CAS:全称Compareandswap&#xff0c;字⾯意思:”⽐较并交换“&#xff0c;⼀个CAS涉及到以下操作&#xff1a; 我们假设内存中的原数据V&#xff0c;旧的预期值A&#xff0c;需要修改的新值B。 1. ⽐较A与V是否相等。&#xff08;⽐较&#xff09; 2. 如果⽐较…

ubuntu22.04单个网口两个IP

其中 4网段IP可用来上网&#xff0c;3 网段用来内网 界面显示: 配置文件&#xff1a; 01-network-manager-all.yaml 放在 /etc/netplan/ # Let NetworkManager manage all devices on this systemnetwork:version: 2renderer: networkdethernets:eth0:dhcp4: falsedhcp6: …

开放式耳机哪个牌子好?五大超值机型整理,速速收藏!!

大家都知道现在的开放式耳机是越来越火了&#xff0c;后台也有非常多的小伙伴来私信&#xff0c;作为一个耳机测评师&#xff0c;当然是为了你们服务啦&#xff0c;所以这一期文章&#xff0c;就是为了个大家答疑解惑&#xff0c;告诉大家如何才能选购出一款比较好用的开放式耳…

万字长文详解Java反射技术 | JavaSE | Java进阶知识 | 源码

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a; 神马都会亿点点的毛毛张 &#x1f4cc;今天分享的是JavaSE中的进阶知识&#x1f6d1;&#xff1a;反射技术。内容有点长&#xff0c;非常全面&#xff0c;记得点赞&#x1f44d;、收藏✅加关…

【网络世界】HTTP协议

目录 &#x1f308;前言&#x1f308; &#x1f4c1; 概念 &#x1f4c1; URL &#x1f4c2; urlencode 和 urldecode &#x1f4c1; 协议格式 &#x1f4c1; 方法 &#x1f4c2; GET/get &#x1f4c2; POST/post &#x1f4c1; 常见的报头 &#x1f4c1; 状态码 &…

模型大小的指标和模型量化的指标和手段

一、模型大小的指标 1.计算量 计算次数&#xff0c;反映了模型对硬件计算单元的需求。计算量的单位是 OPs(Operations) 。最常用的数据格式 为 float32&#xff0c;因此float32类型下的计算量单位被写作 FLOPs (Floating Point Operations)&#xff0c;即浮点计算次数。模型的…