当前位置: 首页 > news >正文

udp网络通信 socket

套接字是实现进程间通信的编程。IP可以标定主机在全网的唯一性,端口可以标定进程在主机的唯一性,那么socket通过IP+端口号就可以让两个在全网唯一标定的进程进行通信。

套接字有三种:

域间套接字:实现主机内部的进程通信的编程

原始套接字:使用网络层或者数据链路层的接口进行编程,更难更底层,例如制作抓包等网络工具

网络套接字:实现用户通信的编程

udp网络通信

服务端server

分析:

服务端最少需要有两个接口,一个用来初始化服务器,一个用来运行服务器

一:初始化服务器接口

创建socket,绑定端口

1.创建socket

socket接口

fedd87d5c4ed451a98cd741758e1fd65.png

第一个参数是域,用来确定通信类型27575ae93e4e46ccb56a96cff6bdffbb.png 

AF_UNIX就是域间套接字,AF_INET/AF_INET6是IPv4/IPv6的网络套接字

第二个参数是传输的数据种类 

1885a033313f4789a12b066d2b3a3cf2.png

最常用的是前两个,SOCK_STREAM是面向字节流(TCP),SOCK_DGRAM是面向数据报(UDP)

第三个参数传0即可,这里用不到 

0ddec27613af48f6ad4685f1ac6a541c.png

返回值返回一个文件描述符 

2.绑定端口

bind接口

1dac49aa4920483c96a1505b8fcbfff7.png

第一个参数是socket返回的文件描述符

第二个参数是一个包含通信属性的结构体,例如通信域,ip地址和端口号。这是一个输出型参数,而且不同的通信类型的结构体不一样,传参时要进行类型转换。

47ab09aafd6d47729a411520d3c0fba1.png

c84c77ee04cf4e0b821d436be4789ae2.png

sockaddr_in有三个成员需要我们初始化:
1.sin_family:通信域,网络通信使用AF_INET

这个成员使用了宏函数,宏传入参数sin_,所以sa_prefix##family等价于sin_family,它是一个无符号短整型

2.sin_port:端口号 

端口号会在网络间传输,需要对我们传入的端口号进行处理,使其符合网络字节序,要使用htons()接口

3.sin_addr:ip地址

这个成员是一个结构体,结构体内有一个无符号整形的成员。但是我们一般的ip地址是一个字符串例如(192.168.33.131),所以我们要先将字符串转化为数字,再将数字变为网络字节序。这要用到inet_addr(char*)接口

第三个参数时结构体大小,直接计算即可

注意:一般服务器bind的ip地址是0.0.0.0,如果一个服务是绑定到 0.0.0.0 ,那么外部机器访问该机器上所有 IP 都可以访问该服务。如果服务绑定到的是特定的 ip,则只有访问该 ip 才能访问到服务。

 初始化服务器代码样例:

class udpserver{
public:void init(){// 创建udp serversockfd_ = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd_ < 0){exit(1);}// bind socked//初始化结构体struct sockaddr_in local;local.sin_family = AF_INET;local.sin_port = htons(port_);                  // 转化成网络字节序local.sin_addr.s_addr = inet_addr(ip_.c_str()); // 将ip转化成数字,再将数字转化为网络字节序//bindif (bind(sockfd_, (struct sockaddr *)&local, sizeof(local)) < 0){exit(2);}}udpserver(uint16_t port = 8080, string ip = "0.0.0.0"): port_(port), ip_(ip){}~udpserver(){if (sockfd_ > 0)close(sockfd_);}
private:int sockfd_;uint16_t port_;string ip_;
};

二:运行服务器接口

接收数据,对数据做处理,最后发送数据

1.接收数据

recvfrom接口

c0a1d65b28404ddba7faec9ae3462b78.png

90acb0527a354fff915010617d47967d.png

第一个参数是socket返回的文件描述符,第二个是接收的数据存放的位置,第三个参数是buf空间的大小,第四个参数在本文中这里只要传0即可满足需求。

第五个参数是用来存储数据发送方(客户端)属性的结构体,第六个参数是结构体大小的指针

为什么要记录客户端的通信属性呢?因为服务端在对数据做处理后还要发送回客户端。 

 2.对数据做处理

需要根据实际需求进行处理,可以通过传函数指针,实现代码分层。见后面的代码示例。

3.发送数据

sendto接口

a2a60ee6474c46c883e5e79d428a34a5.png

5faa90bb08204028a1a991b756f61956.png

 第一个参数是socket的文件描述符,第二个参数是要发送的数据的地址,第三个参数是发送数据的大小,第四个参数传0。

第五个参数是数据接收方(客户端)属性的结构体,第六个参数是结构体大小。

运行服务器代码样例(包括前面的代码):

//udpserver.hpp
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <functional>
using func = function<string(char*)>;
class udpserver{
public:void init(){// 创建udp serversockfd_ = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd_ < 0){exit(1);}// bind socked//初始化结构体struct sockaddr_in local;local.sin_family = AF_INET;local.sin_port = htons(port_);                  // 转化成网络字节序local.sin_addr.s_addr = inet_addr(ip_.c_str()); // 将ip转化成数字,再将数字转化为网络字节序//bindif (bind(sockfd_, (struct sockaddr *)&local, sizeof(local)) < 0){exit(2);}}void run(func fun){char buf[1024] = {0};while (1){struct sockaddr_in client; // 客户端的信息socklen_t len = sizeof(client);// 收数据ssize_t n = recvfrom(sockfd_, buf, sizeof(buf), 0, (struct sockaddr *)&client, &len);if (n < 0){cout << "receice fail" << endl;continue;}buf[n] = 0;cout << "server get:" << buf << endl;// 处理数据,通过传递的函数实现数据处理的和网络通信解耦string ret = fun(buf);// 发送数据n = sendto(sockfd_, ret.c_str(), ret.size(), 0, (struct sockaddr *)&client, len);}}udpserver(uint16_t port = 8080, string ip = "0,0,0,0"): port_(port), ip_(ip){}~udpserver(){if (sockfd_ > 0)close(sockfd_);}
private:int sockfd_;uint16_t port_;string ip_;
};//main.cpp
#include"udpserver.hpp"
#include<memory>using namespace std;
string datagram(char* data)
{string ret = "Get message:";ret += data;return ret;
}
int main()
{unique_ptr<udpserver> server(new udpserver());server->init();server->run(datagram);return 0;
}

客户端client

分析:

客户端需要初始化客户端,发送数据,接收数据

一:初始化客户端

创建socket和服务端一样,不同的是客户端的bind是操作系统完成的不需要我们操作,客户端会在发送数据时由OS随机bind一个端口。因为客户端的设备可能同时请求多个服务端,例如手机会同时运行很多app,客户端的程序很难为服务端留一个固定的端口(不同公司之间开发软件不可能商量谁要用哪个客户端的端口),而且服务端没必要第一时间知道客户端的端口,客户端发送数据请求时可以获取到客户端的属性

二:发送数据

使用sendto()接口,和服务端一样。

三:接收数据

使用recvfrom()接口,和服务端一样。

客户端代码样例:

#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>using namespace std;
int main(int argc, char *argv[])
{//获取命令行参数,ip和端口号if(argc != 3){cout << "Please input in this way" << endl;cout << "./udpclient" << " [ip]" << " [port]" << endl;}string ip = argv[1];uint16_t port = stoi(argv[2]);// 创建socketint sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){cout << "client create fail" << endl;}//客户端不需要bind,但是客户端会在发送数据时由OS随机bind一个端口,因为客户端设备同时请求多个服务端,服务端很难让客户端的程序为其留一个固定的端口,而且没必要第一时间知道客户端的端口,客户端发送数据请求时可以获取到// 创建服务端信息的结构体struct sockaddr_in server;server.sin_port = htons(port);server.sin_family = AF_INET;server.sin_addr.s_addr = inet_addr(ip.c_str());socklen_t len = sizeof(server);char buf[1024] = {0};string message;while (1){// 发送数据cout << "Please Enter@";getline(cin, message);sendto(sockfd, message.c_str(), message.size(), 0, (struct sockaddr *)&server, len);// 接收数据struct sockaddr_in tem;socklen_t len_tem = sizeof(tem);ssize_t n = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&tem, &len_tem);if (n < 0){cout << "client receive fail" << endl;continue;}buf[n] = 0;cout << buf << endl;}
}

相关文章:

udp网络通信 socket

套接字是实现进程间通信的编程。IP可以标定主机在全网的唯一性&#xff0c;端口可以标定进程在主机的唯一性&#xff0c;那么socket通过IP端口号就可以让两个在全网唯一标定的进程进行通信。 套接字有三种&#xff1a; 域间套接字&#xff1a;实现主机内部的进程通信的编程 …...

LG AI研究开源EXAONE 3.0:一个7.8B双语语言模型,擅长英语和韩语,在实际应用和复杂推理中表现出色

EXAONE 3.0介绍&#xff1a;愿景与目标 EXAONE 3.0是LG AI研究所在语言模型发展中的一个重要里程碑&#xff0c;特别是在专家级AI领域。 “EXAONE”这个名称源自于“ EX pert A I for Every ONE”&#xff0c;反映了LG AI研究所致力于将专家级别的人工智能能力普及化的承诺。这…...

【mysql】mysql之主从部署以及介绍

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…...

Invoke-Maldaptive:一款针对LDAP SearchFilter的安全分析工具

关于Invoke-Maldaptive MaLDAPtive 是一款针对LDAP SearchFilter的安全分析工具&#xff0c;旨在用于对LDAP SearchFilter 执行安全解析、混淆、反混淆和安全检测。 其基础是 100% 定制的 C# LDAP 解析器&#xff0c;该解析器处理标记化和语法树解析以及众多自定义属性&#x…...

QT 读取Excel表

一、QAxObject 读取excel表的内容&#xff0c;其仅在windows下生效&#xff0c;当然还有其他跨平台的方案。 config qaxcontainer #include <QAxObject>QStringList GetSheets(const QString& strPath) {QAxObject* excel new QAxObject("Excel.Application&…...

深入理解 Vue 组件样式管理:Scoped、Deep 和 !important 的使用20240909

深入理解 Vue 组件样式管理&#xff1a;Scoped、Deep 和 !important 的使用 在前端开发中&#xff0c;样式的管理与组件化开发之间的平衡一直是一个难题。Vue.js 提供了一些强大的工具来帮助开发者在开发复杂的应用时管理样式。这篇文章将详细介绍 Vue 中的 scoped、:deep() 和…...

C语言内存函数(21)

文章目录 前言一、memcpy的使用和模拟实现二、memmove的使用和模拟实现三、memset函数的使用四、memcmp函数的使用总结 前言 正文开始&#xff0c;发车&#xff01; 一、memcpy的使用和模拟实现 函数模型&#xff1a;void* memcpy(void* destination, const void* source, size…...

三高基本概念之-并发和并行

并行和并发是计算机科学中两个重要但容易混淆的概念&#xff0c;它们之间的主要区别可以从以下几个方面进行阐述&#xff1a; 一、定义与含义 并行&#xff08;Parallel&#xff09;&#xff1a;并行是指两个或多个事件在同一时刻发生&#xff0c;即这些事件在微观和宏观上都…...

宝塔面板FTP连接时“服务器发回了不可路由的地址。使用服务器地址代替。”

参考 https://blog.csdn.net/neizhiwang/article/details/106628899 错误描述 我得服务器是腾讯&#xff0c;然后使用宝塔建了个HTML网站&#xff0c;寻思用ftp上传&#xff0c;结果报错&#xff1a; 状态: 连接建立&#xff0c;等待欢迎消息... 状态: 初始化 TLS 中... 状…...

面试的一些小小经验

无论何时&#xff0c;找到合适的满意的工作&#xff08;距离住处的地理位置&#xff0c;薪资&#xff0c;工作氛围&#xff09;并不是一件容易的事情。个人能力与职位的适配性永远是有误差的客观存在。 十全十美难得&#xff0c;满足个人的个体化优先级才是客观的存在。 1.投简…...

IV转换放大器原理图及PCB设计分析

【前言】 今天给大家分享一下关于IV转换放大器的相关电路设计心得。IV转换使用的场合非常之多&#xff0c;尤其是电流型输出的传感器&#xff0c;比如光敏二极管、硅光电池等等&#xff0c;这些传感器输出的电流信号非常微弱&#xff0c;我们如果需要检测它们&#xff0c;首先得…...

【数学建模经验贴】一个研赛数模老手的经验

我&#xff08;非C君&#xff0c;是一个朋友&#xff09;参加了3次“深圳杯”数模&#xff0c;1次全国大学生数模&#xff0c;以及1次全国研究生数模&#xff0c;2016年参加了全国研究生数模的交流会&#xff0c;但没有参加过美赛&#xff0c;应该算是一个江湖老手了吧。下面内…...

vivo手机已删除的短信还能恢复吗?

虽然现在我们很少使用vivo手机的短信功能&#xff0c;但是我们偶尔还会通过vivo手机短信功能接收一些重要的信息。如果我们在清理垃圾短信的时候误删了vivo手机重要短信&#xff0c;该怎么恢复呢&#xff1f; 方法一&#xff1a;通过vivo云服务恢复 1、确保您已开启vivo云服务…...

[网络][CISCO]CISCO IOS升级

CISCO IOS升级-&#xff08;转&#xff09;2008-06-27 15:35IOS 升级 在介绍CISCO路由器IOS升级方法前&#xff0c;有必要对Cisco路由器的存储器的相关知识作以简单介绍。路由器与计算机相似&#xff0c;它也有内存和操作系统。在Cisco路由器中&#xff0c;其操作系统叫做互连…...

通过python提取PDF文件指定页的图片

整体思路 要从 PDF 文件中提取指定页和指定位置的图片&#xff0c;可以分几个步骤来实现&#xff1a; 1.1 准备所需工具与库 在 Python 中处理 PDF 和图像时&#xff0c;需要使用几个库&#xff1a; PyMuPDF (fitz)&#xff1a;用于读取和处理 PDF 文件&#xff0c;可以精确…...

Leetcode Hot 100刷题记录 -Day12(轮转数组)

轮转数组 问题描述&#xff1a; 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4]解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向…...

GitHub每日最火火火项目(9.13)

以下是对这些项目的详细介绍&#xff1a; fishaudio 的 fish-speech&#xff1a; 基本信息&#xff1a;这是一种全新的语音技术解决方案&#xff0c;属于文本到语音&#xff08;Text-to-Speech&#xff0c;TTS&#xff09;技术范畴。技术特点&#xff1a; 多语言支持&#xff…...

力扣--649.Dota2参议院

Dota2 的世界里有两个阵营&#xff1a;Radiant&#xff08;天辉&#xff09;和 Dire&#xff08;夜魇&#xff09; Dota2 参议院由来自两派的参议员组成。现在参议院希望对一个 Dota2 游戏里的改变作出决定。他们以一个基于轮为过程的投票进行。在每一轮中&#xff0c;每一位参…...

vim 安装与配置教程(详细教程)

vim就是一个功能非常强大的文本编辑器&#xff0c;可以自己DIY的那种 &#xff0c;不但可以写代码 &#xff0c;还可编译 &#xff0c;可以让你手不离键盘的完成鼠标的所有操作。 如果想要了解vim的的发展历史和详细解说&#xff0c;可以自行上网搜索&#xff0c;我主要是记录一…...

【WPF】Popup的使用

WPF&#xff08;Windows Presentation Foundation&#xff09;中的Popup控件用于创建弹出窗口&#xff0c;如工具提示、上下文菜单等。Popup控件本身并不直接显示任何内容&#xff0c;它需要一个子元素来显示实际的内容。 以下是一个简单的XAML示例&#xff0c;展示如何创建一…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...