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

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;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 速盾:cdn 缓存图片
  • Vue基础知识:Vue3.3出现的defineOptions,如何使用,解决了什么问题?
  • 2. 年龄问题
  • 高效利用iCloud指南
  • Python中的类和对象:如何定义一个类以及如何创建类的实例(对象)
  • 网络安全合规建设
  • Nginx在线安装与启动
  • Stable Diffusion图像的脸部细节控制——采样器全解析
  • 【基于R语言群体遗传学】-13-群体差异量化-Fst
  • 移动应用开发课设——原神小助手文档(2)
  • nvidia driver和cuda版本较低,ubuntu系统更新nvidia驱动的方法(对于小白最快最最保险的方法)
  • 近红外光谱脑功能成像(fNIRS):2.实验设计、指标计算与多重比较
  • pbootCMS 数据库sqlite转mysql数据库
  • VSCode使用Makefile管理工程
  • 人工智能算法工程师(中级)课程1-Opencv视觉处理之基本操作
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • JavaScript函数式编程(一)
  • Quartz初级教程
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • Webpack4 学习笔记 - 01:webpack的安装和简单配置
  • 半理解系列--Promise的进化史
  • 笨办法学C 练习34:动态数组
  • 分布式熔断降级平台aegis
  • 工作手记之html2canvas使用概述
  • 构建工具 - 收藏集 - 掘金
  • 将回调地狱按在地上摩擦的Promise
  • 如何实现 font-size 的响应式
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • 跳前端坑前,先看看这个!!
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 微服务入门【系列视频课程】
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • 阿里云API、SDK和CLI应用实践方案
  • ​力扣解法汇总946-验证栈序列
  • ​业务双活的数据切换思路设计(下)
  • # 安徽锐锋科技IDMS系统简介
  • #《AI中文版》V3 第 1 章 概述
  • #Spring-boot高级
  • $().each和$.each的区别
  • (2024,RWKV-5/6,RNN,矩阵值注意力状态,数据依赖线性插值,LoRA,多语言分词器)Eagle 和 Finch
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (8)STL算法之替换
  • (delphi11最新学习资料) Object Pascal 学习笔记---第7章第3节(封装和窗体)
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (k8s)Kubernetes本地存储接入
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (排序详解之 堆排序)
  • (七)Knockout 创建自定义绑定
  • (三分钟)速览传统边缘检测算子
  • (学习日记)2024.02.29:UCOSIII第二节
  • (一)Mocha源码阅读: 项目结构及命令行启动
  • (译) 函数式 JS #1:简介
  • (转)fock函数详解
  • (转)jQuery 基础