UDP通讯实现

服务器端:

1.获取套接字

	int fd;fd=socket(AF_INET,SOCK_DGRAM,0);if(fd<0){perror("socket");exit(0);}

#include <sys/types.h>

#include <sys/socket.h>

int socket(int domain, int type, int protocol);

-domain: 指定通信域(通信地址族);

-type: 指定套接字类型;    数据报套接字:SOCK_DGRAM

-protocol: 指定协议;     数据报接字唯一对应TCP,所以无需要指定协议,设为0即可

2.绑定套接字

	struct sockaddr_in addr;bzero(&addr,sizeof(addr));addr.sin_port=htons(atoi(argv[2]));//man inet_aton,判断地址转换是否成功if((inet_aton(argv[1],&addr.sin_addr))==0){fprintf(stderr,"Invalid address\n");//表示将“Invalid address”给标准错误stderrexit(0);}if(bind(fd,(struct sockaddr *)&addr,sizeof(addr))<0){perror("bind");exit(0);}

函数1:

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

-sockfd:socket函数生成的套接字

-addr:通信结构体

-addrlen:通信结构体的长度

注意:参数addr是通用结构体sockaddr,要将初始化的sock_in结构体强制转换

struct sockaddr_in { sa_family_t    sin_family;

/* 地址族: AF_INET */ in_port_t      sin_port;  

/* 网络字节序的端口号 */ struct in_addr sin_addr;  

/*IP地址结构体 */ };

/* IP地址结构体 */ struct in_addr { uint32_t       s_addr;     /* 网络字节序的IP地址 */ };

函数2:

在C语言中,inet_aton函数用于将表示IPv4地址的字符串转换为网络字节序的32位二进制数。该函数的原型如下:

int inet_aton(const char *cp, struct in_addr *inp);

其中:

  • cp是一个指向表示IPv4地址的字符串的指针。
  • inp是一个指向in_addr结构的指针,用于存储转换后的IPv4地址。

函数返回值为整型,如果字符串成功转换为IPv4地址,则返回1;如果转换失败,则返回0。

函数3:

`bzero()` 函数用于将指定长度的内存区域清零,即将所有字节初始化为0。它通常用于清空敏感的数据或准备数据结构。`bzero()` 函数在许多系统中已经被废弃,应该使用更现代的函数`memset()` 来替代。其原型如下:
void bzero(void *s, size_t n);

其中,参数 `s` 是指向要清零的内存区域的指针,参数 `n` 是要清零的字节数。

3.接收数据

	while(1){bzero(buf,BUFSIZ);recvfrom(fd,buf,BUFSIZ,0,NULL,NULL);printf("buf=%s\n",buf);}close(fd);

函数原型:ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                          struct sockaddr *src_addr, socklen_t *addrlen);

功能:接收数据,并将接收到的数据存放到buf指向的缓冲区中。

参数说明:
- sockfd:要接收数据的套接字文件描述符。
- buf:指向用于存放接收数据的缓冲区。
- len:缓冲区的长度。
- flags:一些控制接收操作的标志。
- src_addr:指向发送方的地址结构体的指针。
- addrlen:发送方地址结构体的长度。

返回值:成功接收到数据时,返回接收到的数据的长度;失败时,返回-1并设置errno。

原始代码

#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<strings.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<unistd.h>
int main(int argc ,char *argv[]){int fd;char buf[BUFSIZ]={};struct sockaddr_in addr;if(argc<3){fprintf(stderr,"%s<addr><port>\n",argv[0]);exit(0);}fd=socket(AF_INET,SOCK_DGRAM,0);if(fd<0){perror("socket");exit(0);}bzero(&addr,sizeof(addr));addr.sin_port=htons(atoi(argv[2]));//man inet_aton,判断地址转换是否成功if((inet_aton(argv[1],&addr.sin_addr))==0){fprintf(stderr,"Invalid address\n");//表示将“Invalid address”给标准错误stderrexit(0);}if(bind(fd,(struct sockaddr *)&addr,sizeof(addr))<0){perror("bind");exit(0);}while(1){bzero(buf,BUFSIZ);recvfrom(fd,buf,BUFSIZ,0,NULL,NULL);printf("buf=%s\n",buf);}close(fd);return 0;
}

客户端:

1.获取套接字

	int fd;fd=socket(AF_INET,SOCK_DGRAM,0);if(fd<0){perror("socket");exit(0);}

#include <sys/types.h>

#include <sys/socket.h>

int socket(int domain, int type, int protocol);

-domain: 指定通信域(通信地址族);

-type: 指定套接字类型;    数据报套接字:SOCK_DGRAM

-protocol: 指定协议;     数据报接字唯一对应TCP,所以无需要指定协议,设为0即可

2.发送数据

	char buf[BUFSIZ]={};struct sockaddr_in addr;socklen_t addrlen;addrlen=sizeof(addr);bzero(&addr,sizeof(addr));addr.sin_port=htons(atoi(argv[2]));//man inet_aton,判断地址转换是否成功if((inet_aton(argv[1],&addr.sin_addr))==0){fprintf(stderr,"Invalid address\n");//表示将“Invalid address”给标准错误stderrexit(0);}while(1){bzero(buf,BUFSIZ);printf("input>");fgets(buf,BUFSIZ,stdin);sendto(fd,buf,strlen(buf),0,(struct sockaddr *)&addr,addrlen);}

函数1:

在C语言中,inet_aton函数用于将表示IPv4地址的字符串转换为网络字节序的32位二进制数。该函数的原型如下:

int inet_aton(const char *cp, struct in_addr *inp);

其中:

  • cp是一个指向表示IPv4地址的字符串的指针。
  • inp是一个指向in_addr结构的指针,用于存储转换后的IPv4地址。

函数返回值为整型,如果字符串成功转换为IPv4地址,则返回1;如果转换失败,则返回0。

函数2:

`bzero()` 函数用于将指定长度的内存区域清零,即将所有字节初始化为0。它通常用于清空敏感的数据或准备数据结构。`bzero()` 函数在许多系统中已经被废弃,应该使用更现代的函数`memset()` 来替代。其原型如下:
void bzero(void *s, size_t n);

其中,参数 `s` 是指向要清零的内存区域的指针,参数 `n` 是要清零的字节数。

函数3:

sendto函数用于向指定的套接字发送数据。其声明如下:

```c
#include <sys/types.h>
#include <sys/socket.h>

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
```

参数解释:
- `sockfd`: 要发送数据的套接字文件描述符。
- `buf`: 指向要发送的数据的指针。
- `len`: 要发送的数据的长度。
- `flags`: 指定发送数据时的标志,通常为0。
- `dest_addr`: 目标地址的结构体指针,其中包含目标主机的IP地址和端口号。
- `addrlen`: 目标地址结构体的长度。

成功发送数据时,sendto函数返回发送的字节数。如果发生错误,则返回-1,并设置errno变量指示错误原因。
 

注意:

1.nc -u +IP地址+端口号,连接服务器,本地回环

2.udp停止服务器端,再开启后,客户端也是可以正常发送,服务器端正常接收

原始代码:

#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<strings.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<unistd.h>
#include<string.h>
int main(int argc ,char *argv[]){int fd;char buf[BUFSIZ]={};struct sockaddr_in addr;socklen_t addrlen;addrlen=sizeof(addr);if(argc<3){fprintf(stderr,"%s<addr><port>\n",argv[0]);exit(0);}fd=socket(AF_INET,SOCK_DGRAM,0);if(fd<0){perror("socket");exit(0);}bzero(&addr,sizeof(addr));addr.sin_port=htons(atoi(argv[2]));//man inet_aton,判断地址转换是否成功if((inet_aton(argv[1],&addr.sin_addr))==0){fprintf(stderr,"Invalid address\n");//表示将“Invalid address”给标准错误stderrexit(0);}while(1){bzero(buf,BUFSIZ);printf("input>");fgets(buf,BUFSIZ,stdin);sendto(fd,buf,strlen(buf),0,(struct sockaddr *)&addr,addrlen);}close(fd);return 0;
}

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

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

相关文章

Elasticsearch 面试题指南

Elasticsearch 面试题指南 本文档提供了一份详细的 Elasticsearch 面试题指南&#xff0c;涵盖了 Elasticsearch 的核心概念、架构、配置、操作和实际应用场景等方面的内容。希望通过这份指南能够帮助你在 Elasticsearch 面试中取得成功。 目录 Elasticsearch 基础知识 什么…

Retrofit框架源码深度剖析【Android热门框架分析第二弹】

Android热门框架解析&#xff0c;你确定不来看看吗&#xff1f; OkHttp框架源码深度剖析【Android热门框架分析第一弹】 Retrofit框架源码深度剖析【Android热门框架分析第二弹】 什么是Retrofit&#xff1f; 准确来说&#xff0c;Retrofit 是一个 RESTful 的 HTTP 网络请求…

网络编程:数据包的封装----libnet库

使用libnet库封装数据包 安装库sudo apt-get install libnet-dev 1、数据包内存初始化 libnet_t *libnet_init(int injection_type, char *device, char *err_buf) 2、构造数据包&#xff0c; 由应用层UDP/TCP到MAC层的顺序构造 封装udp数据包的函数 libnet_ptag_t libnet_bui…

Miniconda的常见用法——以Isaacgym为例

1. ubuntu24.04安装minicondda mkdir -p ~/miniconda3 wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh解释下这段代码 bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3~/miniconda3/miniconda.sh: 指向Mi…

java中Function、Consumer和Supplier是函数式接口吗?

是的&#xff0c;在Java中&#xff0c;Function、Consumer 和 Supplier 都是函数式接口&#xff0c;它们都是Java 8引入的java.util.function包中的一部分。这些接口为Lambda表达式提供了类型支持&#xff0c;允许以更简洁的方式表示方法引用和匿名内部类。 Function<T, R&g…

SHARPNESS-AWARE MINIMIZATION FOR EFFICIENTLY IMPROVING GENERALIZATION--论文笔记

论文笔记 资料 1.代码地址 https://github.com/google-research/sam https://github.com/davda54/sam 2.论文地址 https://arxiv.org/abs/2010.01412 3.数据集地址 论文摘要的翻译 在当今严重过度参数化的模型中&#xff0c;训练损失的值很难保证模型的泛化能力。事实上…

代码随想录算法训练营第三十天|62.不同路径、63. 不同路径 II

62.不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&#xff…

软设之生成器模式

生成器模式的意图是:将一个复杂的类表示与其构造分离&#xff0c;使得相同的构建过程能够得出不同的表示 Builder:抽象建造者&#xff0c;为创建一个产品对象各个部件指定抽象接口&#xff0c;把产品的生产过程分解为不同的步骤&#xff0c;从而使具体建造者在具体的建造步骤上…

Java中的对象克隆详解

Java中的对象克隆详解 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 对象克隆在Java编程中是一个重要的概念和技术。它允许我们创建一个对象的精确副本&…

MySQL第三次练习

作业三 一 先创建DB abc&#xff0c;创建table student 1、插入一条记录 2、添加多条记录 3、添加部分记录 4、加0.5 5、删除成绩为空的记录 二 1、创建一个用户test1使他只能本地登录拥有查询student表的权限。 2、查询用户test1的权限。 3、删除用户test1. 全在一张图上…

怎样优化 PostgreSQL 中对日期时间范围的模糊查询?

文章目录 一、问题分析&#xff08;一&#xff09;索引未有效利用&#xff08;二&#xff09;日期时间格式不统一&#xff08;三&#xff09;复杂的查询条件 二、优化策略&#xff08;一&#xff09;使用合适的索引&#xff08;二&#xff09;规范日期时间格式&#xff08;三&a…

AI学习指南机器学习篇-层次聚类(Hierarchical Clustering)简介

AI学习指南机器学习篇-层次聚类(Hierarchical Clustering)简介 在机器学习领域中&#xff0c;层次聚类(Hierarchical Clustering)是一种常见的无监督学习算法&#xff0c;用于将数据集中的样本分成具有相似特征的群组。层次聚类不需要预先指定要分成的群组数目&#xff0c;而是…

逻辑回归模型(非回归问题,而是分类问题)

目录&#xff1a; 一、Sigmoid函数&#xff1a;二、逻辑回归介绍&#xff1a;三、决策边界四、逻辑回归模型训练过程&#xff1a;1.训练目标&#xff1a;2.梯度下降调整参数&#xff1a; 一、Sigmoid函数&#xff1a; Sigmoid函数是构建逻辑回归模型的重要函数&#xff0c;如下…

免费压缩pdf文件大小软件收费吗?pdf如何压缩文件大小?12款压缩应用推荐!

在数字化时代&#xff0c;PDF文件因其跨平台、格式统一的特点而广受欢迎。然而&#xff0c;随着文件内容的增加&#xff0c;PDF文件的大小也逐渐增大&#xff0c;给存储和传输带来了诸多不便。因此&#xff0c;寻找一款合适的PDF压缩软件成为了许多用户的需求。本文将详细介绍1…

单调队列与单调栈(集训day2)

一、目录 1、单调队列 2、单调栈 二、正文 1.单调栈题型&#xff1a; &#xff08;1&#xff09;给出一个数组找出其中每个数左边第一个比它小&#xff08;大&#xff09;的数字 830. 单调栈 - AcWing题库 &#xff08;2&#xff09;求直方图中最大的矩形&…

电子设备常用的胶水有哪些?

目录 1、502胶水 2、703胶水 3、704胶水 4、AB胶 5、红胶 6、Underfill 7、导电胶 8、UV胶 9、热熔胶 10、环氧树脂胶 11、硅酮胶 12、聚氨酯胶 13、丙烯酸胶 14、丁基胶 1、502胶水 502胶水&#xff0c;也被称为瞬间胶或快干胶&#xff0c;是一种非常常见的粘合…

电动卡丁车语音芯片方案选型:让驾驶体验更智能、更安全

在追求速度与激情的电动卡丁车领域&#xff0c;每一次升级都意味着更加极致的驾驶体验。而今天&#xff0c;我们要介绍的&#xff0c;正是一款能够显著提升电动卡丁车智能化与安全性的语音芯片方案——为您的爱车增添一份独特的魅力与安全保障。 智能化升级&#xff0c;从“听…

[Python学习篇] Python面向对象——继承

继承是什么 继承是面向对象编程&#xff08;OOP&#xff09;中的一个核心概念。继承允许一个类&#xff08;称为子类或派生类&#xff09;从另一个类&#xff08;称为父类或基类&#xff09;继承属性和方法。这样可以重用代码&#xff0c;提高代码的模块化和可维护性。 父类&am…

js面试题2024

1.js的数据类型 boolean number string null undefined bigint symbol object 按存储方式分&#xff0c;前面七种为基本数据类型&#xff0c;存储在栈上&#xff0c;object是引用数据类型&#xff0c;存储在堆上&#xff0c;在栈中存储指针 按es标准分&#xff0c;bigint 和sym…