以下是基于UDP协议的完整客户端和服务器代码。UDP与TCP的核心区别在于无连接特性,因此代码结构会更简单(无需监听和接受连接)。

UDP服务器代码(udp_server.cpp)

#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>int main() {// 1. 创建UDP套接字(SOCK_DGRAM表示UDP)int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd == -1) {std::cerr << "Failed to create socket" << std::endl;return 1;}// 2. 绑定IP和端口struct sockaddr_in server_addr;memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = htonl(INADDR_ANY);  // 监听所有IPserver_addr.sin_port = htons(9888);  // UDP端口if (bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {std::cerr << "Failed to bind socket" << std::endl;close(sockfd);return 1;}std::cout << "UDP Server started, listening on port 9888..." << std::endl;// 3. 接收客户端数据并回复char buffer[1024];struct sockaddr_in client_addr;socklen_t client_addr_len = sizeof(client_addr);while (true) {  // 循环接收多个客户端消息// 接收客户端数据(自动获取客户端地址)memset(buffer, 0, sizeof(buffer));int recv_len = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&client_addr, &client_addr_len);if (recv_len == -1) {std::cerr << "Failed to receive data" << std::endl;continue;  // 继续接收其他客户端消息}// 打印客户端信息和消息char client_ip[INET_ADDRSTRLEN];inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, INET_ADDRSTRLEN);std::cout << "Received from " << client_ip << ":" << ntohs(client_addr.sin_port) << ": " << buffer << std::endl;// 回复客户端std::string response = "Hello, client! I got your message: " + std::string(buffer);sendto(sockfd, response.c_str(), response.size(), 0, (struct sockaddr*)&client_addr, client_addr_len);}// 4. 关闭套接字(实际不会执行到这里,需按Ctrl+C终止)close(sockfd);return 0;
}

UDP客户端代码(udp_client.cpp)

#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
using namespace std;int main() {// 1. 创建UDP套接字int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd == -1) {std::cerr << "Failed to create socket" << std::endl;return 1;}// 2. 设置服务器地址struct sockaddr_in server_addr;memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(9888);  // 服务器端口inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);  // 服务器IP// 3. 发送消息并接收回复string message = "Hello, UDP server!";sendto(sockfd, message.c_str(), message.size(), 0, (struct sockaddr*)&server_addr, sizeof(server_addr));// 接收服务器回复char buffer[1024];struct sockaddr_in server_response_addr;socklen_t server_addr_len = sizeof(server_response_addr);memset(buffer, 0, sizeof(buffer));int recv_len = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&server_response_addr, &server_addr_len);if (recv_len == -1) {std::cerr << "Failed to receive response" << std::endl;close(sockfd);return 1;}cout << "Received from server: " << buffer << endl;// 4. 关闭套接字close(sockfd);return 0;
}

核心差异对比(TCP vs UDP)

特性TCPUDP
连接方式面向连接(三次握手/四次挥手)无连接(直接发送)
套接字类型SOCK_STREAMSOCK_DGRAM
核心APIbind→listen→accept→connectbind(仅服务器需要)
数据传输函数read/writesend/recvsendto/recvfrom
可靠性可靠(自动重传、按序到达)不可靠(可能丢包、乱序)
通信流程先建立连接,再固定双方通信每次发送需指定目标地址

UDP编程关键点说明

  1. 无连接特性

    • 服务器无需 listen()accept(),直接接收数据;
    • 客户端无需 connect(),直接向服务器地址发送数据。
  2. 核心函数 sendto()recvfrom()

    // 发送数据到指定地址
    ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);// 从指定地址接收数据(自动获取发送方地址)
    ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
    
    • 每次发送/接收都需指定对方地址(struct sockaddr*),因此UDP可与多个不同目标通信(无固定连接)。
  3. UDP服务器的多客户端处理

    • 单个套接字可处理多个客户端(通过 recvfrom() 获取客户端地址,sendto() 回复特定客户端);
    • 无需为每个客户端创建新套接字(与TCP不同)。
  4. 数据边界

    • UDP是“数据报”协议,发送的数据有明确边界(发送几次就接收几次,不会粘包);
    • 接收缓冲区需足够大,否则会导致数据截断(如发送1000字节,但缓冲区只有512字节,则仅接收前512字节)。

编译和运行步骤

  1. 编译程序:

    g++ udp_server.cpp -o udp_server
    g++ udp_client.cpp -o udp_client
    
  2. 启动服务器:

    ./udp_server
    # 输出:UDP Server started, listening on port 9888...
    
  3. 启动客户端(新终端):

    ./udp_client
    # 输出:Received from server: Hello, client! I got your message: Hello, UDP server!
    
  4. 服务器端会显示:

    Received from 127.0.0.1:xxxx: Hello, UDP server!
    

    xxxx 是客户端随机分配的端口号)

适用场景

  • UDP:适合实时性要求高、允许少量丢包的场景(如视频/语音通话、游戏、实时监控)。
  • TCP:适合可靠性要求高、数据完整性重要的场景(如文件传输、网页浏览、邮件)。

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

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

相关文章

King’s LIMS:实验室数字化转型的智能高效之选

实验室数字化转型不仅是技术升级&#xff0c;更是管理理念和工作方式的革新。LIMS系统作为这一转型的核心工具&#xff0c;能够将分散的实验数据转化为可分析、可复用的资产&#xff0c;为科研决策提供支持&#xff1b;规范检测流程&#xff0c;减少人为干预&#xff0c;确保结…

【力扣 中等 C】97. 交错字符串

目录 题目 解法一 题目 待添加 解法一 bool isInterleave(char* s1, char* s2, char* s3) {const int len1 strlen(s1);const int len2 strlen(s2);const int len3 strlen(s3);if (len1 len2 ! len3) {return false;}if (len1 < len2) {return isInterleave(s2, s1,…

Class9简洁实现

Class9简洁实现 %matplotlib inline import torch from torch import nn from d2l import torch as d2l# 初始化训练样本、测试样本、样本特征维度和批量大小 n_train,n_test,num_inputs,batch_size 20,100,200,5 # 设置真实权重和偏置 true_w,true_b torch.ones((num_inputs…

ELK日志分析,涉及logstash、elasticsearch、kibana等多方面应用,必看!

目录 ELK日志分析 1、下载lrzsc 2、下载源包 3、解压文件,下载elasticsearch、kibana、 logstash 4、配置elasticsearch 5、配种域名解析 6、配置kibana 7、配置logstash 8、进行测试 ELK日志分析 1、下载lrzsc [rootlocalhost ~]# hostnamectl set-hostname elk ##…

终极剖析HashMap:数据结构、哈希冲突与解决方案全解

文章目录 引言 一、HashMap底层数据结构&#xff1a;三维存储架构 1. 核心存储层&#xff08;硬件优化设计&#xff09; 2. 内存布局对比 二、哈希冲突的本质与数学原理 1. 冲突产生的必然性 2. 冲突概率公式 三、哈希冲突解决方案全景图 1. 链地址法&#xff08;Hash…

1.1.5 模块与包——AI教你学Django

1.1.5 模块与包&#xff08;Django 基础学习细节&#xff09; 模块和包是 Python 项目组织和代码复用的基础。Django 项目本质上就是由多个模块和包组成。理解和灵活运用模块与包机制&#xff0c;是写好大型项目的关键。 一、import、from-import、as 的用法 1. import 用于导入…

UE5 相机后处理材质与动态参数修改

一、完整实现流程1. 创建后处理材质材质设置&#xff1a;在材质编辑器中&#xff0c;将材质域(Material Domain)设为后处理(Post Process)设置混合位置(Blendable Location)&#xff08;如After Tonemapping&#xff09;创建标量/向量参数&#xff08;如Intensity, ColorTint&a…

Django基础(三)———模板

前言 在之前的文章中&#xff0c;视图函数只是直接返回文本&#xff0c;而在实际生产环境中其实很少这样用&#xff0c;因为实际的页面大多是带有样式的HTML代码&#xff0c;这可以让浏览器渲染出非常漂亮的页面。目前市面上有非常多的模板系统&#xff0c;其中最知名最好用的…

mysql6表清理跟回收空间

mysql6表清理跟回收空间 文章目录mysql6表清理跟回收空间1.清理表2.备份表或者备份库3.回收表空间4.查看5.验证业务1.清理表 ## 登录 C:\Program Files\MySQL\MySQL Server 5.6\bin>mysql -uroot -p Enter password: ****** Welcome to the MySQL monitor. Commands end w…

Java-74 深入浅出 RPC Dubbo Admin可视化管理 安装使用 源码编译、Docker启动

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; AI炼丹日志-30-新发布【1T 万亿】参数量大模型&#xff01;K…

VSCode同时支持Vue2和Vue3开发的插件指南

引言 随着Vue生态系统的演进&#xff0c;许多开发者面临着在同一开发环境中同时处理Vue 2和Vue 3项目的需求。Visual Studio Code (VSCode)作为最受欢迎的前端开发工具之一&#xff0c;其插件生态对Vue的支持程度直接影响开发效率。本文将深入探讨如何在VSCode中配置插件组合&a…

卷积神经网络CNN的Python实现

一、环境准备与库导入 在开始实现卷积神经网络之前&#xff0c;需要确保开发环境已正确配置&#xff0c;并导入必要的Python库。常用的深度学习框架有TensorFlow和PyTorch&#xff0c;本示例将基于Keras&#xff08;可使用TensorFlow后端&#xff09;进行实现&#xff0c;因为K…

js是实现记住密码自动填充功能

记住密码自动填充使用js实现记住密码功能&#xff0c;在下次打开登陆页面的时候进行获取并自动填充到页面【cookie和localStorage】使用js实现记住密码功能&#xff0c;在下次打开登陆页面的时候进行获取并自动填充到页面【cookie和localStorage】 //添加功能----记住上一个登陆…

【Java】文件编辑器

代码&#xff1a;&#xff08;SimpleEditor.java&#xff09;import java.awt.Color; import java.awt.Font; import java.awt.Insets; import java.awt.BorderLayout;import java.awt.event.ActionEvent; import java.awt.event.ActionListener;import java.io.BufferedReader…

PyTorch中torch.topk()详解:快速获取最大值索引

torch.topk(similarities, k=2).indices 是什么意思 torch.topk(similarities, k=2).indices 是 PyTorch 中用于获取张量中最大值元素及其索引的函数。在你的代码中,它的作用是从 similarities 向量里找出得分最高的2个元素的位置索引。 1. 核心功能:找出张量中最大的k个值…

快速搭建本地HTTP服务器:`python -m http.server`详解

文章目录 一、什么是 http.server? 二、基础使用 1. 启动服务器 2. 指定端口 3. 绑定特定IP 三、实际应用场景 1. 本地前端开发 2. 文件共享 3. 启用CGI脚本(高级) 四、目录浏览详解* 五、安全注意事项 六、进阶技巧 1. 后台运行(Linux/macOS) 2. 自定义错误页面 3. 结合其…

运维技术教程之Jenkins上的known_hosts文件

在Jenkins中&#xff0c;known_hosts文件用于存储已验证的远程节点主机密钥&#xff0c;避免每次连接时重复验证。以下是基于不同场景的解决方案&#xff1a;1. 创建并配置 known_hosts 文件 若Jenkins提示 No Known Hosts file 或找不到文件&#xff0c;需手动创建并配置&…

leetcode 3201. 找出有效子序列的最大长度 I 中等

给你一个整数数组 nums。nums 的子序列 sub 的长度为 x &#xff0c;如果其满足以下条件&#xff0c;则称其为 有效子序列&#xff1a;(sub[0] sub[1]) % 2 (sub[1] sub[2]) % 2 ... (sub[x - 2] sub[x - 1]) % 2返回 nums 的 最长的有效子序列 的长度。一个 子序列 指的…

Java并发编程第三篇(深入解析Synchronized)

1. Synchronized简介&#xff1a;一个常见的并发“陷阱” 在正式开始学习新知识前&#xff0c;我们不妨先来看一个现象&#xff0c;这是一个很多并发编程新手都会遇到的“陷阱”&#xff1a; public class SynchronizedDemo implements Runnable {// 共享变量private static in…

Chatbox AI|多模型多模态交互+MCP,一个工具打造你的全能私人助手

ChatBoxAI集成GPT-4、Claude等顶尖模型&#xff0c;支持Windows/macOS/Linux多平台&#xff0c;具备隐私加密、文件智能解析&#xff08;PDF/代码/图片&#xff09;及开发者友好特性。其应用覆盖自媒体创作、代码实时预览、AI绘图&#xff08;封面/表情包&#xff09;及联网搜索…