UDP通讯实现

news2024/12/24 16:36:57

服务器端:

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”给标准错误stderr
		exit(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”给标准错误stderr
		exit(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”给标准错误stderr
		exit(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”给标准错误stderr
		exit(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.coloradmin.cn/o/1908751.html

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

相关文章

LabVIEW中自定义Ring控件的图标

在LabVIEW中&#xff0c;自定义Ring控件的图标可以让用户界面更加直观和友好。以下是如何在LabVIEW中自定义Ring控件的图标的详细步骤&#xff1a; 步骤1&#xff1a;创建或获取图标 首先&#xff0c;你需要创建或获取你想要在Ring控件中使用的图标。你可以使用图像编辑软件&…

前端面试题27(在实际项目中,如何有效地利用Vue3的响应式系统提高性能?)

在实际项目中&#xff0c;有效利用Vue3的响应式系统提高性能主要涉及以下几个关键点&#xff1a; 1. 合理使用reactive和ref reactive&#xff1a;用于将复杂的数据结构&#xff08;如对象或数组&#xff09;转换成响应式版本。确保只将需要实时更新的数据结构声明为响应式&am…

VsCode崩溃无法打开解决办法

今天打开电脑 点开vscode突然不能使用了 每次点开都闪退,于是查找解决办法 直接重启电脑 这个方法没有解决问题 删除软件 重新安装软件 软件删干净之前保存下自己的配置文件 比如扩展和settings.json和keybinding.json Mac系统 在 /Users/用户名/.vscode/extensions 和/User…

jmeter测试工具学习

1.双击jar包打开&#xff0c;发现那个bat打不开 2.新建plan之后编辑添加线程组 会加入500*5次请求 3.添加HTTP请求 添加字段 为了让http请求发送到不同的分片&#xff0c;要把userid随机化 4.添加监听器 5.聚合报告

【大模型搭建】部署Ollama,pull失败,手动构建方案

Ollama 是一个专注于简化大规模机器学习模型开发的框架。它提供了一系列工具来帮助开发者轻松地定义、训练和部署大型语言模型。 优点&#xff1a; • 提供了简洁的API&#xff0c;易于上手。 • 支持多种硬件加速选项&#xff0c;如GPU和TPU。 • 内置了许多预训练模型&#x…

MGRE复习综合实验

R1与R5之间使用ppp的pap认证&#xff0c;R5为主认证方&#xff1a; R1 interface Serial4/0/0ip address 15.0.0.1 8link-protocol pppppp pap local-user huawei password cipher 123456 R5 aaalocal-user huawei password cipher 123456local-user huawei service-type…

java中 使用数组实现需求小案例

Date: 2024.04.08 18:32:57 author: lijianzhan 需求实现&#xff1a; 设计一个java类&#xff0c;java方法&#xff0c;根据用户手动输入的绩点&#xff0c;从而获取到绩点最高的成绩。 实现业务逻辑的代码块 import java.util.Scanner;public class PointDemo {/*** 需求&…

中国计量大学理学院访问赛氪网:共探校企合作新篇章来

2024年7月5日&#xff0c;中国计量大学理学院代表团莅临环球赛乐&#xff08;北京&#xff09;科技有限公司&#xff0c;进行了一场深入的调研交流活动。代表团成员包括中国计量大学理学院副院长王义康教授、数据科学系副主任刘学艺副教授以及金世举老师。此次访问旨在进一步强…

wordpress外贸建站公司案例英文模板

Indirect Trade WP外贸网站模板 WordPress Indirect Trade外贸网站模板&#xff0c;建外贸独立站用wordpress模板&#xff0c;快速搭建十分便捷。 衣物清洁wordpress独立站模板 洗衣粉、洗衣液、衣物柔顺剂、干洗剂、衣领净、洗衣皂等衣物清洁wordpress独立站模板。 家具wordpr…

00 Debian字符界面如何支持中文

作者&#xff1a;网络傅老师 特别提示&#xff1a;未经作者允许&#xff0c;不得转载任何内容。违者必究&#xff01; Debian字符界面如何支持中文 《傅老师Debian知识库系列之00》——原创 前言 傅老师Debian知识库特点&#xff1a; 1、拆解Debian实用技能&#xff1b; 2、…

前端视角下的Spring-Boot语法学习:打印 hello-world

今日话题 基于 Spring Boot 打印输出 hello world 作者&#xff1a;云层上的光 时间&#xff1a;2024年6月20日 14时25分14秒 主线任务 一、打印 hello world 1、点击 “新建项目”用来演示 打印输出 “hello world” 2、填写项目配置&#xff1a;&#xff08;详细版见&a…

MYSQL 四、mysql进阶 7(性能分析工具的使用)

一、数据库服务器的优化步骤 数据库调优流程图: 整个流程划分成了 观察&#xff08;Show status&#xff09; 和 行动&#xff08;Action&#xff09; 两个部分。字母 S 的部分代表观察&#xff08;会使 用相应的分析工具&#xff09;&#xff0c;字母 A 代表的部分是行…

利用 Python 解析pcap文件

1、问题背景 当面对处理网络数据包分析时&#xff0c;pcap文件作为一个常见的文件格式存储了网络数据包的详细记录&#xff0c;它常常被用来进行网络故障排查或安全分析。为了充分利用这些数据&#xff0c;我们需要对其进行解析并提取出有价值的信息&#xff0c;例如数据包类型…

Git 查看、新建、删除、切换分支

Git 是一个版本控制系统&#xff0c;软件开发者用它来跟踪应用程序的变化并进行项目协作。 分支的诞生便于开发人员在彼此独立的环境中进行开发工作。主分支&#xff08;通常是 main 或 master&#xff09;可以保持稳定&#xff0c;而新的功能或修复可以在单独的分支中进行开发…

Angular进阶之九: JS code coverage是如何运作的

环境准备 需要用到的包 node 18.16.0# Javascript 代码编辑"babel/core": "^7.24.7","babel/preset-env": "^7.24.7","babel-loader": "^9.1.3",# 打包时使用的 module&#xff0c; 给代码中注入新的方法# http…

基于51单片机的四路抢答器Protues仿真设计

一、设计背景 近年来随着科技的飞速发展&#xff0c;单片机的应用正在不断的走向深入。本文阐述了基于51单片机的八路抢答器设计。本设计中&#xff0c;51单片机充当了核心控制器的角色&#xff0c;通过IO口与各个功能模块相连接。按键模块负责检测参与者的抢答动作&#xff0c…

js替换对象内部的对象名称或属性名称-(第二篇)递归

1.代码示例&#xff1a; function replaceKey(obj, oldKey, newKey) {// 如果不是对象或者oldKey不存在&#xff0c;直接返回原对象if (typeof obj ! object || !obj || !(oldKey in obj)) return obj;// 如果是数组&#xff0c;遍历数组每个元素if (Array.isArray(obj)) {obj…

python爬虫加入进度条

安装tqdm和requests库 pip install tqdm -i https://pypi.tuna.tsinghua.edu.cn/simplepip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple带进度条下载 import time # 引入time模块&#xff0c;用于处理时间相关的功能 from tqdm import * # 从tqdm包中…

ESIX配置备份和恢复

ESIX虽然重装很快&#xff0c;但是原本配置就丢失了&#xff0c;在硬件不变的情况下&#xff0c;可以使用配置备份和配置恢复的方法。 1、备份配置 1.1、执行以下两条命令 vim-cmd hostsvc/firmware/sync_configvim-cmd hostsvc/firmware/backup_config如下图&#xff0c;只需…

LED灯的呼吸功能

"呼吸功能"通常是指 LED 灯的一种工作模式&#xff0c;它模拟人类的呼吸节奏&#xff0c;即 LED 灯的亮度会周期性地逐渐增强然后逐渐减弱&#xff0c;给人一种 LED 在"呼吸"的感觉。这种效果通常用于指示设备的状态或者简单地作为装饰效果。&#xff08;就…