Linux网络编程6——UDP通信

news/2025/2/10 20:25:04/

一.UDP通信

1.TCP通信和UDP通信各自的优缺点

TCP:	面向连接的,可靠数据包传输。对于不稳定的网络层,采取完全弥补的通信方式。 丢包重传。​	优点:
​		稳定。		
​			数据流量稳定、速度稳定、顺序
​	缺点:
​		传输速度慢。相率低。开销大。​	使用场景:数据的完整型要求较高,不追求效率。​		  大数据传输、文件传输。UDP:	无连接的,不可靠的数据报传递。对于不稳定的网络层,采取完全不弥补的通信方式。 默认还原网络状况​	优点:​		传输速度块。相率高。开销小。​	缺点:
​		不稳定。
​			数据流量。速度。顺序。​	使用场景:对时效性要求较高场合。稳定性其次。​		  游戏、视频会议、视频电话。		腾讯、华为、阿里  ---  应用层数据校验协议,弥补udp的不足。

2.UDP实现的 C/S 模型

  • recv()/send() 只能用于 TCP 通信。 替代 read、write

  • accpet(); ---- Connect(); —被舍弃

server

	lfd = socket(AF_INET, STREAM, 0);	SOCK_DGRAM --- 报式协议。bind();listen();  --- 可有可无while(1){read(cfd, buf, sizeof) --- 被替换 --- recvfrom() --- 涵盖accept传出地址结构。ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);sockfd: 套接字buf:缓冲区地址len:缓冲区大小flags: 0src_addr:(struct sockaddr *)&addr 传出。 对端地址结构addrlen:传入传出。返回值: 成功接收数据字节数。 失败:-1 errn。 0: 对端关闭。小-- 大write();--- 被替换 --- sendto()---- connectssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);sockfd: 套接字buf:存储数据的缓冲区len:数据长度flags: 0src_addr:(struct sockaddr *)&addr 传入。 目标地址结构addrlen:地址结构长度。返回值:成功写出数据字节数。 失败 -1, errno		}close();

client

	connfd = socket(AF_INET, SOCK_DGRAM, 0);​	sendto(‘服务器的地址结构’, 地址结构大小)​	recvfrom()​	写到屏幕​	close();

3.代码

server.cpp:

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>#define SERV_PORT 9527int main()
{int sockfd;sockfd = socket(AF_INET,SOCK_DGRAM,0);             //表示选择UDP协议char buf[1024],clie_IP[BUFSIZ];int ret;struct sockaddr_in serv_addr,clie_addr;socklen_t clie_addr_len = sizeof(clie_addr);serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(SERV_PORT);serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);bind(sockfd,(struct soakaddr *)&serv_addr,sizeof(serv_addr));     //绑定服务器的信息while(1){ret =n recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&clie_addr,&clie_addr_len);printf("client 's IP:%s   port:%d\n", inet_ntop(AF_INET,&clie_addr.sin_addr.s_addr,clie_IP,sizeof(clie_IP)),ntohs(clie_addr.sin_port));for(int i = 0;i<ret;i++)buf[i] = toupper(buf[i]);sendto(socket,buf,ret,0,(struct sockaddr *)*clie_addr,clie_addr_len);}close(sockfd);
}

cilent.cpp:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <ctype.h>#define SERV_PORT 8000int main(int argc, char *argv[])
{struct sockaddr_in servaddr;int sockfd, n;char buf[BUFSIZ];sockfd = socket(AF_INET, SOCK_DGRAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);servaddr.sin_port = htons(SERV_PORT);bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));while (fgets(buf, BUFSIZ, stdin) != NULL) {n = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));if (n == -1)perror("sendto error");n = recvfrom(sockfd, buf, BUFSIZ, 0, NULL, 0);         //NULL:不关心对端信息if (n == -1)perror("recvfrom error");write(STDOUT_FILENO, buf, n);}close(sockfd);return 0;
}

二.本地套接字

1.回顾/了解

进程间通信:

  • pipe管道:应用性最强
  • FIFO有名管道:可以在没有血缘关系间进行通信
  • mmap共享内存:没有血缘关系间通信且可以返回读取
  • 信号:开销最小
  • 本地套接字(domain):稳定性最好

对比网络编程的TCP的C/S模型,注意以下几点:

函数原型:

#include <sys/socket.h>int socket(int domain, int type, int protocol);
  • domain:用来指定传输协议,网络套接字使用AF_INETAF_INET6分别表示IPv4和IPv6,而本地套接字需要使用AF_UNIXAF_LOCAL
  • type:用来指定协议类型,可以取SOCK_STREAM表示流式协议或SOCK_DGRAM表示报式协议
  • protocol:传0表示默认协议

type为SOCK_STREAM且protocol=0表示使用TCP传输,type为SOCK_DGRAM且protocol=0表示使用UDP传输。


第二步,注意bind函数的地质结构体发生变化,由原来的sockaddr_in变成了sockaddr_un

struct sockaddr_in {
__kernel_sa_family_t sin_family; 			/* Address family */  	地址结构类型
__be16 sin_port;					 	/* Port number */		端口号
struct in_addr sin_addr;					/* Internet address */	IP地址
};
struct sockaddr_un {
__kernel_sa_family_t sun_family; 		/* AF_UNIX */			地址结构类型
char sun_path[UNIX_PATH_MAX]; 		/* pathname */		socket文件名(含路径)
};

变化代码

2. 地址结构:  sockaddr_in --> sockaddr_unstruct sockaddr_in srv_addr; --> struct sockaddr_un srv_adrr;srv_addr.sin_family = AF_INET;  --> srv_addr.sun_family = AF_UNIX;
·srv_addr.sin_port = htons(8888);    strcpy(srv_addr.sun_path, "srv.socket")srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);			len = offsetof(struct sockaddr_un, sun_path) + strlen("srv.socket");bind(fd, (struct sockaddr *)&srv_addr, sizeof(srv_addr));  --> 	bind(fd, (struct sockaddr *)&srv_addr, len); 
  1. bind()函数调用成功,会创建一个 socket。因此为保证bind成功,通常我们在 bind之前, 可以使用 unlink(“srv.socket”);
4. 客户端不能依赖 “隐式绑定”。并且应该在通信建立过程中,创建且初始化2个地址结构:1) client_addr --> bind()2)  server_addr --> connect();

http://www.ppmy.cn/news/1570952.html

相关文章

stm32电机驱动模块

电机驱动模块是智能车等电子设备中用于驱动电机运转的重要部件&#xff0c;它能将微控制器输出的控制信号转换为足够的功率和电流来驱动电机。以下为你详细介绍电机驱动模块的相关信息&#xff1a; 常见类型 1. L298N 电机驱动模块 特点 高电压、大电流驱动能力&#xff1a;能…

Dart语言的云计算

Dart语言在云计算中的应用 引言 云计算作为一种新兴的计算模式&#xff0c;为各行各业带来了重大变革。借助于云计算&#xff0c;用户可以通过互联网获取和使用各种资源&#xff0c;如计算能力、存储、数据库等。随着云计算的快速发展&#xff0c;编程语言的选择变得愈发重要…

Java 一键将 Word 文档转为 PDF

嘿&#xff0c;朋友们&#xff01;在开发中&#xff0c;经常会碰到需要把 Word 文档转换成 PDF 格式的需求&#xff0c;像生成报告、合同啥的。Java 有不少好用的库能实现这个功能&#xff0c;下面就给大家介绍两种常见的方法&#xff0c;分别使用 Apache POI 和 Docx4J 结合 i…

在Mac mini M4上部署DeepSeek R1本地大模型

在Mac mini M4上部署DeepSeek R1本地大模型 安装ollama 本地部署&#xff0c;我们可以通过Ollama来进行安装 Ollama 官方版&#xff1a;【点击前往】 Web UI 控制端【点击安装】 如何在MacOS上更换Ollama的模型位置 默认安装时&#xff0c;OLLAMA_MODELS 位置在"~/.o…

Python----Python高级(网络编程:网络基础:发展历程,IP地址,MAC地址,域名,端口,子网掩码,网关,URL,DHCP,交换机)

一、网络 早期的计算机程序都是在本机上运行的&#xff0c;数据存储和处理都在同一台机器上完成。随着技术的发展&#xff0c;人 们开始有了让计算机之间相互通信的需求。例如安装在个人计算机上的计算器或记事本应用&#xff0c;其运行环 境仅限于个人计算机内部。这种设置虽然…

探索robots.txt:网站管理者的搜索引擎指南

在数字时代&#xff0c;网站如同企业的在线名片&#xff0c;其内容和结构对搜索引擎的可见性至关重要。而在这背后&#xff0c;有一个默默工作的文件——robots.txt&#xff0c;它扮演着搜索引擎与网站之间沟通桥梁的角色。本文将深入探讨robots.txt的功能、编写方法及其在现代…

AI时代医疗大健康微服务编程提升路径和具体架构设计

一、引言 1.1 研究背景与意义 随着科技的飞速发展,人工智能(Artificial Intelligence,AI)已逐渐渗透至各个领域,医疗大健康领域亦不例外。人工智能与医疗大健康的融合,正引领着医疗行业迈向智能化、精准化、个性化的新时代,为解决医疗资源分布不均、提升医疗服务效率和…

Qt监控设备离线检测/实时监测设备上下线/显示不同的状态图标/海康大华宇视华为监控系统

一、前言说明 监控系统中一般有很多设备&#xff0c;有些用户希望知道每个设备是否已经上线&#xff0c;最好有不同的状态图标提示&#xff0c;海康的做法是对设备节点的图标和颜色变暗处理&#xff0c;离线的话就变暗&#xff0c;有可能是加了透明度&#xff0c;而大华的处理…