Linux编程(通信协议---udp)

    UDP(用户数据报协议)是一种无连接的网络协议,主要用于快速传输数据。以下是UDP协议的一些主要特点:

1. **无连接**:UDP是无连接的协议,这意味着在数据传输之前不需要建立连接。每个UDP数据包都是独立的,不需要前一个数据包的确认。

2. **简单性**:UDP的协议结构相对简单,只有8字节的UDP头部,包括源端口、目的端口、长度和校验和。

3. **快速性**:由于UDP不需要建立连接和进行数据确认,因此它的数据传输速度通常比TCP快。

4. **不保证可靠性**:UDP不保证数据的可靠传输,也就是说,数据包可能会丢失、重复或乱序到达。

5. **无拥塞控制**:UDP没有拥塞控制机制,这意味着它不会根据网络的拥堵情况调整数据传输速率。

6. **支持多播和广播**:UDP支持多播和广播数据传输,这使得它可以用于发送数据到多个接收者。

7. **校验和**:UDP包含一个校验和字段,用于检测数据在传输过程中是否出现错误。如果检测到错误,接收方可以选择丢弃该数据包。

8. **应用场景**:UDP通常用于那些对实时性要求高但可以容忍一定数据丢失的应用,如视频会议、在线游戏、DNS查询等。

9. **端口号**:UDP使用端口号来区分不同的服务或进程,每个UDP数据包都包含源端口和目的端口。

10. **数据报长度**:UDP数据报的长度可以是任意的,但最大长度受限于IP数据报的最大长度,通常是65507字节。
 


2、框架: C/S模式 

  服务器端  server:socket() ===>bind()===>recvfrom()===>close()
   客户端  client:socket() ===>bind()===>sendto() ===>close()


注意:socket()的参数需要调整。

      socket(PF_INET,SOCK_DGRAM,0);

  bind() 客户端是可选的,服务器端是必须选的。

1、int socket(int domain, int type, int protocol);
功能:程序向内核提出创建一个基于内存的套接字描述符

参数:domain  地址族,PF_INET == AF_INET ==>互联网程序
  PF_UNIX == AF_UNIX ==>单机程序
  type    套接字类型:
     SOCK_STREAM  流式套接字 ===》TCP   
  SOCK_DGRAM   用户数据报套接字===>UDP
  SOCK_RAW     原始套接字  ===》IP
  protocol 协议 ==》0 表示自动适应应用层协议。

返回值:成功 返回申请的套接字id
失败  -1;

2、int bind(int sockfd, struct sockaddr *my_addr, 
             socklen_t addrlen);
功能:如果该函数在服务器端调用,则表示将参数1相关
  的文件描述符文件与参数2 指定的接口地址关联,
  用于从该接口接受数据。

  如果该函数在客户端调用,则表示要将数据从
  参数1所在的描述符中取出并从参数2所在的接口
  设备上发送出去。

  注意:如果是客户端,则该函数可以省略,由默认
        接口发送数据。
参数:sockfd 之前通过socket函数创建的文件描述符,套接字id
  my_addr 是物理接口的结构体指针。表示该接口的信息。

  struct sockaddr      通用地址结构
  {
  u_short sa_family;  地址族
  char sa_data[14];   地址信息
  };

  转换成网络地址结构如下:
  struct _sockaddr_in    ///网络地址结构
  {
  u_short    sin_family; 地址族
  u_short    sin_port;   ///地址端口
  struct in_addr  sin_addr;   ///地址IP
  char    sin_zero[8]; 占位
  };

  struct in_addr
  {
  in_addr_t s_addr;
  }

  socklen_t addrlen: 参数2 的长度。
返回值:成功 0
失败  -1;

发送接收函数:
3、ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
         const struct sockaddr *dest_addr, socklen_t addrlen);

功能:用于UDP协议中向对方发送数据。
参数:sockfd  本地的套接字id
  buff    本地的数据存储,一般是要发送的数据。
  len     要发送的数据长度
  flags   要发送数据方式,0 表示阻塞发送。

  dest_addr: 必选,表示要发送到的目标主机信息结构体。
  addrlen :目标地址长度。

返回值:成功  发送的数据长度
    失败   -1;


4、ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                  struct sockaddr *src_addr, socklen_t *addrlen);

功能:用于UDP协议中获取对方发送的数据。
参数:sockfd 本地的套接字id
  buff   要存储数据的内存区,一般是数组或者动态内存。
  len    要获取的数据长度,一般是buff的大小。
  flags  获取方式,0 阻塞

  src_addr 可选,表示对方的地址信息结构体,
   如果为NULL,表示不关心对方地址。
  addrlen  对方地址信息结构体大小。
   如果对方地址是NULL,则该值也为NULL。
返回值:成功 接收到的数据长度
失败  -1;

《1》实现udp通信示例代码:

服务器端:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
typedef struct sockaddr * (SA);
int main(int argc, char *argv[])
{int sockfd = socket(AF_INET,SOCK_DGRAM,0);if(-1 == sockfd){perror("socket");exit(1);}// man 7 ip struct sockaddr_in ser,cli;bzero(&ser,sizeof(ser));bzero(&cli,sizeof(cli));ser.sin_family = AF_INET;// 大小端转化 host to net short ser.sin_port = htons(50000);ser.sin_addr.s_addr = inet_addr("192.168.203.128");int ret = bind(sockfd,(SA)&ser,sizeof(ser));if(-1 == ret){perror("bind");exit(1);}socklen_t len = sizeof(cli);while(1){char buf[512]={0};recvfrom(sockfd,buf,sizeof(buf),0,(SA)&cli,&len);time_t tm;time(&tm);sprintf(buf,"%s %s",buf,ctime(&tm));sendto(sockfd,buf,strlen(buf),0,(SA)&cli,len);}close(sockfd);return 0;
}

客户端:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
typedef struct sockaddr * (SA);int main(int argc, char *argv[])
{int sockfd = socket(AF_INET,SOCK_DGRAM,0);if(-1 == sockfd){perror("socket");exit(1);}struct sockaddr_in ser;bzero(&ser,sizeof(ser));ser.sin_family = AF_INET;// 大小端转化 host to net short ser.sin_port = htons(50000);ser.sin_addr.s_addr = inet_addr("192.168.203.128");while(1){char buf[512]="hello,this is udp test";sendto(sockfd,buf,strlen(buf),0,(SA)&ser,sizeof(ser));bzero(buf,sizeof(buf));recvfrom(sockfd,buf,sizeof(buf),0,NULL,NULL);printf("buf is %s\n",buf);sleep(1);}close(sockfd);return 0;
}

《2》udp实现文件传输

服务器端:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
#include <fcntl.h>
typedef struct sockaddr * (SA);
int main(int argc, char *argv[])
{int sockfd = socket(AF_INET,SOCK_DGRAM,0);if(-1 == sockfd){perror("socket");exit(1);}// man 7 ip struct sockaddr_in ser,cli;bzero(&ser,sizeof(ser));bzero(&cli,sizeof(cli));ser.sin_family = AF_INET;// 大小端转化 host to net short ser.sin_port = htons(50000);//ser.sin_addr.s_addr = inet_addr("127.0.0.1");ser.sin_addr.s_addr = INADDR_ANY;int ret = bind(sockfd,(SA)&ser,sizeof(ser));if(-1 == ret){perror("bind");exit(1);}socklen_t len = sizeof(cli);int fd = open("2.png",O_WRONLY|O_CREAT|O_TRUNC,0666);if(-1 == fd){perror("open");exit(1);}while(1){char buf[512]={0};int rd_ret = recvfrom(sockfd,buf,sizeof(buf),0,(SA)&cli,&len);if(0 == strcmp(buf,"^_^")){break;}write(fd,buf,rd_ret);bzero(buf,sizeof(buf));strcpy(buf,"go on");sendto(sockfd,buf,strlen(buf),0,(SA)&cli,len);}close(sockfd);close(fd);return 0;
}

客户端:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
#include <fcntl.h>
typedef struct sockaddr * (SA);int main(int argc, char *argv[])
{int sockfd = socket(AF_INET,SOCK_DGRAM,0);if(-1 == sockfd){perror("socket");exit(1);}struct sockaddr_in ser;bzero(&ser,sizeof(ser));ser.sin_family = AF_INET;// 大小端转化 host to net short ser.sin_port = htons(50000);ser.sin_addr.s_addr = inet_addr("192.168.203.128");int fd = open("/home/linux/1.png",O_RDONLY);if(-1 == fd){perror("open");exit(1);}char buf[512]={0};while(1){bzero(buf,sizeof(buf));int rd_ret = read(fd,buf,sizeof(buf));if(0==rd_ret){break;}sendto(sockfd,buf,rd_ret,0,(SA)&ser,sizeof(ser));bzero(buf,sizeof(buf));recvfrom(sockfd,buf,sizeof(buf),0,NULL,NULL);}bzero(buf,sizeof(buf));strcpy(buf,"^_^");sendto(sockfd,buf,3,0,(SA)&ser,sizeof(ser));close(sockfd);close(fd);return 0;
}

《3》udp实现小聊天室功能

服务器端:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
typedef struct sockaddr * (SA);
typedef enum {CMD_LOGIN,CMD_CHAT,CMD_LOGOUT}TYPE;
typedef struct 
{TYPE type;char name[50];char context[128];}MSG;
typedef struct 
{struct sockaddr_in cli;int flag; // 0  free 1 occu
}LIST;
#define MAX 10
LIST list[MAX]={0};
int do_login(int sockfd,MSG* msg,struct sockaddr_in* cli)
{int i = 0 ;for(i=0;i<MAX;i++){if(1 == list[i].flag ){sendto(sockfd,msg,sizeof(MSG),0,(SA)&list[i].cli,sizeof(list[i].cli));}}for(i=0;i<MAX;i++){if(0 == list[i].flag ){list[i].flag =1;//list[i].cli = *cli;memcpy(&list[i].cli,cli,sizeof(*cli));break;}}return 0;
}int do_chat(int sockfd, MSG* msg,struct sockaddr_in*cli)
{int i = 0 ;for(i=0;i<MAX;i++){if(1 == list[i].flag && 0!=memcmp(&list[i].cli,cli,sizeof(*cli)) ){sendto(sockfd,msg,sizeof(MSG),0,(SA)&list[i].cli,sizeof(list[i].cli));}}
}
int do_logout(int sockfd, MSG* msg,struct sockaddr_in*cli)
{return 0;
}
int main(int argc, char *argv[])
{int sockfd = socket(AF_INET,SOCK_DGRAM,0);if(-1 == sockfd){perror("socket");exit(1);}// man 7 ip struct sockaddr_in ser,cli;bzero(&ser,sizeof(ser));bzero(&cli,sizeof(cli));ser.sin_family = AF_INET;// 大小端转化 host to net short ser.sin_port = htons(50000);ser.sin_addr.s_addr = inet_addr("127.0.0.1");int ret = bind(sockfd,(SA)&ser,sizeof(ser));if(-1 == ret){perror("bind");exit(1);}socklen_t len = sizeof(cli);MSG msg;while(1){bzero(&msg,sizeof(msg));recvfrom(sockfd,&msg,sizeof(msg),0,(SA)&cli,&len);switch(msg.type){case CMD_LOGIN:do_login(sockfd,&msg,&cli);break;case CMD_LOGOUT:do_logout(sockfd,&msg,&cli);break;case CMD_CHAT:do_chat(sockfd,&msg,&cli);break;}}close(sockfd);return 0;
}

客户端:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
typedef struct sockaddr * (SA);
typedef enum {CMD_LOGIN,CMD_CHAT,CMD_LOGOUT}TYPE;
typedef struct 
{TYPE type;char name[50];char context[128];}MSG;
int main(int argc, char *argv[])
{int sockfd = socket(AF_INET,SOCK_DGRAM,0);if(-1 == sockfd){perror("socket");exit(1);}// man 7 ip struct sockaddr_in ser,cli;bzero(&ser,sizeof(ser));ser.sin_family = AF_INET;// 大小端转化 host to net short ser.sin_port = htons(50000);ser.sin_addr.s_addr = inet_addr("127.0.0.1");socklen_t len = sizeof(cli);MSG msg;char name[50]={0};printf("input name:");fgets(name,sizeof(name),stdin);name[strlen(name)-1]='\0';msg.type = CMD_LOGIN;strcpy(msg.name ,name);strcpy(msg.context,"login");sendto(sockfd,&msg,sizeof(msg),0,(SA)&ser,sizeof(ser));pid_t pid = fork();if(pid>0){while(1){bzero(&msg,sizeof(msg));recvfrom(sockfd,&msg,sizeof(msg),0,NULL,NULL);    printf("%s:%s\n",msg.name,msg.context);}}else if(0==pid){while(1){printf("to all");    char buf[128]={0};strcpy(msg.name,name);msg.type = CMD_CHAT;fgets(msg.context,sizeof(msg.context),stdin);//#quitmsg.context[strlen(msg.context)-1]='\0';if(0==strcmp(msg.context,"#quit")){msg.type = CMD_LOGOUT;strcpy(msg.context,"CMD_LOGOUT");}sendto(sockfd,&msg,sizeof(msg),0,(SA)&ser,sizeof(ser));}}else {perror("fork");exit(1);}close(sockfd);return 0;
}

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

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

相关文章

Spark的动态资源分配算法

文章目录 前言基于任务需求进行资源请求的整体过程资源申请的生成过程详解资源申请的生成过程的简单例子资源调度算法的代码解析 申请资源以后的处理&#xff1a;Executor的启动或者结束对于新启动的Container的处理对于结束的Container的处理 基于资源分配结果进行任务调度Pen…

win10删除鼠标右键选项

鼠标右键菜单时&#xff0c;发现里面的选项特别多&#xff0c;找一下属性&#xff0c;半天找不到。删除一些不常用的选项&#xff0c;让右键菜单变得干净整洁。 1、按下键盘上的“winR”组合按键&#xff0c;调出“运行”对话框&#xff0c;输入“regedit”命令&#xff0c;点击…

linux后门教程

linux后门教程 alias 用法 系统默认别名&#xff1a;alias 设置别名&#xff1a;alias lsls -laih 删除别名&#xff1a;unalias ls **加参数&#xff1a;**alias ls‘ls -laih;pwd’ 注意 系统启动默认加载的配置文件 /etc/profile 切换用户就会执行/etc/profile /etc/bash…

Python 实验五 高级数据结构

一、实验目的 &#xff08;1&#xff09;掌握序列的基本操作 &#xff08;2&#xff09;掌握集合、字典的基本操作 二、实验环境 联网计算机一台/每人&#xff0c;内装Windows 7以上操作系统和安装Python 3.7集成开发环境IDLE。 三、实验内容 Sy5-1 列表实现。编写一个…

minIO集成springboot

问题 minIO与spring集成。 步骤 创建桶 创建key 找到创建账号页面&#xff0c;如下图&#xff1a; 点击创建&#xff0c;如下图&#xff1a; 设置如下权限&#xff1a; {"Version": "2012-10-17","Statement": [{"Effect": &q…

codeforces round 948 div2(a,b,c)

题目链接 A #include<bits/stdc.h>using namespace std;#define int long long #define PII pair<int,int>void solve() {int n,m;cin>>n>>m;if(n&1){if((m&1)&&m>1&&m<n)cout<<"YES"<<\n;else…

python的异常

异常 定义 异常是程序执行中发生的错误事件&#xff0c;它可以打断正常的指令流。Python提供了强大的异常处理机制&#xff0c;允许程序在发生错误时执行某些替代指令&#xff0c;而不是直接崩溃。 类型 TypeError&#xff1a;类型错误&#xff0c;比如尝试将字符串和整数相加。…

Jenkins安装nodeJs环境

首先插件市场安装nodeJS插件&#xff0c;我这里已经安装了&#xff0c;没安装的话在 Available plugins 中搜索安装 安装完成后需要下载需要的nodejs版本 新增完成就可以在构建的时候选择当前版本号了

JMeter接口测试之文件上传(参数提取与传递)

参考文档&#xff1a; Jmeter接口测试-文件上传&#xff08;全网最详细的教程&#xff09;_jmeter 文件上传-CSDN博客 1、首先通过fiddler抓取文件上传接口&#xff0c;在Raw的tab页中查看默认请求头以及请求参数 如图所示 2、在jmeter中导入抓取的接口&#xff0c;首先需要配…

新书速览|深入理解Hive:从基础到高阶:视频教学版

《深入理解Hive&#xff1a;从基础到高阶&#xff1a;视频教学版》 本书内容 《深入理解Hive:从基础到高阶:视频教学版》采用“理论实战”的形式编写&#xff0c;通过大量的实例&#xff0c;结合作者多年一线开发实战经验&#xff0c;全面地介绍Hive的使用方法。《深入理解Hiv…

AI算法18-最小角回归算法Least Angle Regression | LARS

​​​ 最小角回归算法简介 最小角回归&#xff08;Least Angle Regression, LAR&#xff09;是一种用于回归分析的统计方法&#xff0c;它在某些方面类似于最小二乘回归&#xff0c;但提供了一些额外的优点。最小角回归由Bradley Efron等人提出&#xff0c;主要用于处理具有…

【Linux】安装PHP扩展-redis

说明 本文档是在centos7.6的环境下&#xff0c;安装PHP7.4之后&#xff0c;安装对应的PHP扩展包redis。 一、下载redis扩展 pecl官方地址:PECL :: The PHP Extension Community Library 下载的版本是&#xff1a;redis-5.3.7.tgz 二、安装redis扩展 1.上传 redis 压缩包到…

【嵌入式DIY实例-ESP8266篇】-LCD ST7789显示DS1307 RTC时间数据

LCD ST7789显示DS1307 RTC时间数据 文章目录 LCD ST7789显示DS1307 RTC时间数据1、硬件准备与接线2、代码实现本文将介绍如何使用 ESP8266 NodeMCU 板和 DS1307 RTC 集成电路构建简单的实时时钟和日历 (RTCC),其中时间和日期打印在 ST7789 TFT 显示模块上。 ST7789 TFT 模块包…

【海外云手机】静态住宅IP集成解决方案

航海大背景下&#xff0c;企业和个人用户对于网络隐私、稳定性以及跨国业务的需求日益增加。静态住宅IP与海外云手机的结合&#xff0c;提供了一种创新的集成解决方案&#xff0c;能够有效应对这些需求。 本篇文章分为三个部分&#xff1b;静态住宅优势、云手机优势、集成解决…

gemini-pro-vision 看图说话

一、安装 pip install -U langchain-google-vertexai 二、设置访问权限 申请服务账号json格式key 三、完整代码 import gradio as gr import json import base64 from pathlib import Path import os import time import requests from fastapi import FastAPI, UploadFile,…

K8S私有云裸金属服务器负载均衡器OpenELB——筑梦之路

OpenELB介绍 OpenELB 是一个专为裸机 Kubernetes 集群设计的开源负载均衡器实现。 在云服务环境中的 Kubernetes 集群里&#xff0c;通常可以用云服务提供商提供的负载均衡服务来暴露 Service&#xff0c;但是在本地没办法这样操作。而 OpenELB 可以让用户在裸金属服务器、边缘…

RocketMQ~架构与工作流程了解

简介 RocketMQ 具有高性能、高可靠、高实时、分布式 的特点。它是一个采用 Java 语言开发的分布式的消息系统&#xff0c;由阿里巴巴团队开发&#xff0c;在 2016 年底贡献给 Apache&#xff0c;成为了 Apache 的一个顶级项目。 在阿里内部&#xff0c;RocketMQ 很好地服务了集…

怎么关闭Windows安全中心?

Windows安全中心是Windows操作系统中的一项重要功能&#xff0c;系统提供这个功能的目的是保护电脑免受各种安全威胁。尽管如此&#xff0c;有时候我们可能出于某些原因需要关闭它。本文将详细介绍如何关闭Windows安全中心&#xff0c;以及需要注意的事项。 重要提醒&#xff1…

搞清c++中的队列(queue)以及双端队列(deque),以及常用的接口!

1. 队列 概念&#xff1a;Queue是一种先进先出(First In First Out,FIFO)的数据结构&#xff0c;它有两个出口 特征&#xff1a; 队列容器允许从一端新增元素&#xff0c;从另一端移除元素 队列中只有队头和队尾才可以被外界使用&#xff0c;因此队列不允许有遍历行为 队列…

这个工具居然能让你的微信暴露得一览无余!!

今天在github看到一个不错的项目&#xff0c;叫做wx-dump-4j&#xff0c;不看不知道&#xff0c;一看吓一跳&#xff0c;这个工具完全的解析了我的微信&#xff01;这个工具准确显示好友数、群聊数和当日消息总量&#xff0c;并且&#xff01;&#xff01;这个工具提供过去15天…