基于数据报(UDP)编程的接口总结

2023-05-16

文章目录

        • Udp编程接口
          • socket():创建套接字
          • bind ():将套接字绑定到指定的网络地址
            • 本机字节序和网络字节序
          • recvfrom()接收一个数据报并保存源地址,从数据报套接字接收数据
            • 调用格式
            • 函数功能
          • sendto():按照指定目的地向数据报套接字发送数据
            • 调用格式
            • 函数功能
          • 实例代码
            • udp_server.cc
            • ucp_client.cc

Udp编程接口

socket():创建套接字
  • 1.使用socket()函数创建一个文件描述符
int socket(AF_INET,SOCK_DGRAM,0);
//参数一:表示改文件描述符使用的是IPV4
//参数二:表示该文件描述符使用的是UDP协议
//参数三:一般不使用
  • 参数domain 用来说明网路程序所在的主机采用的是那种通信协议簇,这些协议族再头文件<sys/socket.h>中定义

  • AF_INET //表示IPv4网络协议

  • AF_INET6 //IPv6网络协议

  • 参数type 用来指明创建的套接字类型,

  • SOCK_STREAM:流式套接字,面向连接可靠的通信类型

  • SOCK_DGRAM:数据报套接字,非面向连接和不可靠的通信类型

  • SOCK_RAW:原始套接字,用来直接访问IP协议

  • 参数protocol 指定套接字使用的协议,一般采用默认值0,表示让系统根据地址格式和套接字类型,自动选择一个合适的协议

  • 返回值:

  • 调用成功就创建了一个新的套接字并返回它的描述符,在之后对该套接字的操作中都要借助这个文件描述符,

  • 否则返回-1(<0) 表示套接字出错.应用程序可调用WSAGetLastError() 获取相应的错误代码

bind ():将套接字绑定到指定的网络地址

使用这个函数前需要将服务器的ip和端口号赋值到结构体sockaddr_in中

使用bind()函数前的准备工作

  • sockaddr 结构:针对各种通信域的套接字,存储它们的地址信息
struct sockaddr{
    u_short sa_family;   /*16位协议家族*/
    char sa_data[14]    /*14字节协议地址*/
};
  • sockaddr_in结构:专门针对Internet通信域,存储套接字相关的网络地址信息(IP地址、传输层端口号等信息)
struct sockadd_in{
  short int sin_family;   //地址家族
  unsigned short int sin_port; //端口号
  struct in_addr sin_addr;  //IP地址
  unsigned char sin_zero[8];  //全为0    
};
  • in_addr 结构:专门用来存储IP地址
struct in_addr{
    unsigned long s_addr;
};
#include<netinet/in.h>
int bind(int sockfd,const struct sockaddr* addr,socklen_t addrlen);
  • 参数sockfd:是未经绑定的套接字文件描述符,是由socket()函数返回的,要将它绑定到指定的网络地址上

  • 参数addr : 是一个指向sockaddr结构变量的指针,所指结构体中保存着特定的网络地址,就是要把套接字sockfd绑定到这个地址上.

  • 参数 addrlen :是结构sockaddr结构的长度,等于sizeof(struct sockadd

  • 返回值

  • 返回0:表示已经正确的实现了绑定

  • 如果返回SOCKET_ERROR表示有错。应用程序可调WSAGetLastError()获取相应的错误代码

  • 最后在函数调用的时候,将这个结构强制转换成sockaddr类型
本机字节序和网络字节序
  • 本机字节序在不同的计算机中,存放多字节值的顺序是不一样的,有的是从低到高,有的是从高到低.计算机中的多字节数据的存储顺序称为本机字节顺序.

  • 网络字节序:在网络协议中,对多字节数据的存储,有它自己的规定。多字节数据在网络协议报头中的存储顺序,称为网络字节序.在套接字中必须使用网络字节序

在这里插入图片描述

所以把IP地址和端口号装入套接字时,我们需要将本机字节序抓换成网络字节序,在本机输出时,我们需要将它们从网络字节序转换成本机字节序

  • 套接字编程接口专门为解决这个问题设置了4个函数

  • 1.htons():短整数本机顺序转换为网络顺序,用于端口号

  • 2.htonl():长整数本机顺序转换成网络顺序,用于IP地址

  • 3.ntohs():短整数网络顺序转换为本机顺序,用于端口号

  • 4.ntohl():长整数网络顺序转换为本机顺序,用于IP地址

这4个函数将被转换的数值作为函数的参数,函数返回值作为转换后的结果

  • 点分十进制的IP地址的转换

在Internet中,IP地址常常是用点分十进制的表示方法,但在套接字中,IP地址是无符号的长整型数,套接字编程接口设置了两个函数,专门用来两种形式IP地址的转换

  • 1.inet_addr函数
unsigned long inet_addr(const char* cp);

/*
入口参cp:点分十进制形式的IP地址
返回值:网络字节顺序的IP地址,是无符号的长整数
*/
  • 2.inet_ntoa函数
char* inet_ntoa(struct in_addr in)

/*
入口参数in: 包含长整数IP地址的in_addr结构变量
返回值:指向点分十进制IP地址的字符串的指针
*/
recvfrom()接收一个数据报并保存源地址,从数据报套接字接收数据
调用格式
int recvfrom(SOCKET s,char *buf,int len,int falgs,
struct sockaddr* from, int* fromlen);
  • 参数s:接收端的数据报套接字描述符,包含接收方的网络地址,从这个套接字接收数据报

  • 参数buf:字符串指针,指向用户进程的接收缓冲区,用来接收从套接字收到的数据报

  • 参数len:用户接收缓冲区的长度,制定了所能接收的最大字节数

  • 参数flags:接收的方式,一般置为0.

  • 参数from: 指向sockaddr 结构的指针,实际上是一个出口参数,当本次调用成功执行后,在这个结构中返回了发送方的网络地址,包括对方的IP地址和端口号

  • 参数fromlen:整数型指针,也是一个出口型参数,本调用结束时,返回存在from中的网络地址长度

  • 返回值: 如果正确接收,则返回实际收到的字节数,如果出错,返回SOCKET_ERROR,应用程序可通过WSAGetLastError()获取相应的错误代码

函数功能
  • 本函数从s套接口 的接收缓冲区队列中,取出第一个数据报,把它放到用户进程 的缓冲区buf中,但最多不超过用户缓冲区的大小。如果数据报大于用户缓冲区长度,那么用户缓冲区中只有数据报的前面部分,后面的数据都会丢失,并且recvfrom()函数WSAEMSGSIZE错误
sendto():按照指定目的地向数据报套接字发送数据
调用格式
int sendto(SOCKET s,char* buf,int len,int flags,struct sockaddr* to,
int tolen)
  • 参数s:发送方的数据报套接字 描述符,包含发送方的网络地址,数据报通过这个套接字向对方发送

  • 参数buf:指向用户进程发送缓冲区的字符串指针,该缓冲区包含将要发送的数据,

  • 参数len:用户发送缓冲区中要发送的数据的长度,是可以发送的最大字节数

  • 参数flags: 指定函数的执行方式,一般置为0.

  • 参数to:指向sockaddr 结构的指针,指定接收数据报的目的套接字的完整的网络地址

  • 参数tolen: to的地址长度,等于sizeof(struct sockaddr)

  • 返回值:如果发送成功,则返回实际发送的字节数,注意这个数字可能小于len中所规定的长度,如果出错返回错误码

函数功能

本函数专用于数据报套接字,用来向发送端的本地套接字发送一个数据报.套接字会将数据下交给传输层的UDP,由它向对方发送.

  • 容易看出,这个调用需要决定通信的两个端点,需要一个全相关的五元组信息,既协议(UDP)、源IP地址、源IP地址、源端口号、目的IP地址和目的端口.通信一端由发送方套接字s指定,通信的另一端由to结构决定
实例代码
udp_server.cc
//先实现UDP版本的服务器

#include<stdio.h>
#include<sys/socket.h>  //socket所用的头文件
#include<netinet/in.h>  //socketaddr_in 结构体的头文件
#include<arpa/inet.h>   //inet.addr的头文件
#include<cstring>
#include<unistd.h>

int main(){
  //1.先创建一个socket
  // AF_INET是一个宏 ,表示使用 ipv4 协议
  //SOCK_DGRAM   表示使用 UDP 协议
  int sock=socket(AF_INET,SOCK_DGRAM,0);
  if(sock<0){
    perror("socket");
    return 1;
  }
  //2.把当前的socket  绑定上一个ip + 端口号
  sockaddr_in addr;   //是一个结构体
  addr.sin_family=AF_INET;
  addr.sin_addr.s_addr = inet_addr("0.0.0.0"); //0.0.0.0将本地所有的ip都包含进来 
  //把点分十进制转换成32位整数
  //设置ip地址
  //ip 地址也是一个整数,也需要转成网络字节序,只不过
  //int_addr 函数自动帮我们转了
  addr.sin_port=htons(8080);
  //端口号必须得先转成网络字节序
  //9090 TCP端口,这个端口不是系统默认的端口,
  //属于自定义的端口
  int ret=bind(sock,(sockaddr*)&addr,sizeof(addr));
  if(ret<0){
    perror("bind");
    return 1;
  }

  printf("server start ok!\n");
  //3.处理服务器收到的请求
  while(true){
    //1.读取客户端的请求
    //面向数据报的函数
    sockaddr_in peer;//获取客户端的ip
    socklen_t len=sizeof(peer);//表示一个整数
    char buf[1024]={0};
    ssize_t n= recvfrom(sock,buf,sizeof(buf)-1,0,(sockaddr*)&peer,&len);
  
    printf("客户端发来消息:%s\n",buf);
    printf("请输入回复内容:");
   if(n<0){
     perror("recvfrom");
     continue;//不要因为一次请求的失利就结束整个程序
   }
   buf[n]='\0';
   //double check
    //2.根据请求计算响应时间
    //[略]此处写的是一个回显服务器(echo server)
    //3.把响应写回客户端
    char buf2[1024]="0";
    scanf("%s",buf2);
    n=sendto(sock,buf2,strlen(buf2),0,(sockaddr*)&peer,len);
    if(n<0){
      perror("sendto");
      continue;
    }
    printf("[%s:%d] buf: %s\n",inet_ntoa(peer.sin_addr),
      ntohs(peer.sin_port), buf2);
  }
  close(sock);
  return 0;
}
ucp_client.cc
//实现UDP版本的客户端

#include<stdio.h>
#include<sys/socket.h>  //socket所用的头文件
#include<netinet/in.h>  //socketaddr_in 结构体的头文件
#include<arpa/inet.h>   //inet.addr的头文件
#include<cstring>
#include<unistd.h>


//./client [ip]
int main(int argc,char *argv[]){

  //1.先创建一个socket
  int sock=socket(AF_INET,SOCK_DGRAM,0);
  if(sock<0){
    perror("socket");
    return 1;
  }
  //2.客户端一般不需要bind
  //bind  意味着和某个具体的端口号关联在一起
  //如果没有bind,操作系统会随机分配一个端口号
  //如果是服务器程序不去bind ,就会导致每次启动服务器的端口发生变化
  //客户端就没法连接了
  //如果客户端bind的话,可能会出现问题
  //通常情况下,一个端口号只能被一个进程bind
  //如果客户端bind一个端口号其他客户端也可能bind同一个端口号
  //就会出错
  //客户端最好还是让操作系统随机分配更科学
  
  //2.准备好服务器的sockaddr_in 结构
  
  sockaddr_in  server_addr;
  server_addr.sin_family=AF_INET;
  server_addr.sin_addr.s_addr=inet_addr(argv[1]);
  server_addr.sin_port=htons(8080);
   
  //3.客户端直接发送数据即可
  while(1){
    char buf[1024]={0};
    printf("请输入一段内容:");
    fflush(stdout);
    scanf("%s",buf);
    sendto(sock,buf,strlen(buf),0,
        (sockaddr*)&server_addr,sizeof(server_addr));
    //从服务器接收一下返回结果
    char buf_output[1024]={0};
    //后两个参数填NULL 表示不关注对端的地址
    recvfrom(sock,buf_output,sizeof(buf_output)-1,0,
          NULL,NULL);
    printf("客户端回应:%s\n",buf_output);
  }
  return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于数据报(UDP)编程的接口总结 的相关文章

  • windows software develop kit 安装卸载笔记

    windows software develop kit 是visual studio 的开发工具库 安装 xff1a 打开Visual Studio Installer中 xff0c 1 Visual Studio Installer所在
  • px4flow智能光学流动传感器

    PX4Flow 是一款智能光学流动传感器 传感器拥有原生 752 480 像素分辨率 xff0c 计算光学流的过程中采用了4倍分级和剪裁算法 xff0c 计算速度达到250Hz xff08 白天 xff0c 室外 xff09 xff0c 具
  • Spring源码之ConfigurableEnvironment Environment ConfigurablePropertyResolver PropertyResolver

    PropertyResolver xff1a 接口以解析任何底层资源的属性 boolean containsProperty String key 返回给定的属性KEY是否可用于解析 xff0c 如果给定密钥的值不是NULL String
  • pyqt setStyleSheet用法

    设置背景 xff1a self content splitter setStyleSheet 34 QSplitter handle background lightgray 34 设置padding self detailFrame pi
  • [音乐] 随遇而安

    黄霑真的很适合唱这种充满了江湖气息的歌 xff0c 这首歌的经典程度不亚于 沧海一声笑 有兴趣的自己搜来听听吧 人外有人山外有山 不怕拼命怕平凡 有得有失有欠有还 老天不许人太贪 挺起胸膛咬紧牙关 生死容易低头难 就算当不成英雄 也要是一条
  • 视觉SLAM十四讲(一)基础知识

    SLAM是Simultaneous Localization and Mapping的缩写 xff0c 中文 同时定位于地图构建 双目SLAM的距离估计是比较左右眼的图像获得的 xff0c 非常消耗计算资源 xff0c 需要使用GPU和FP
  • E-R概念模型

    E R 概念模型 1 信息的现实世界 我们要管理的客观存在的各种事物 事务之间的相互联系及事物的发生 变化过程 1 实体 Entity 现实世界中存在的可以相互区分的事物或概念称为实体 2 实体的特征 Entity Characterist
  • 数据库设计说明书参考模板

    数据库设计说明书参考模板1 xff0e 引言 1 1 项目名称 1 2项目背景和内容概要 xff08 项目的委托单位 开发单位 主管部门 与其它项目的关系 xff0c 与其他机构的关系等 xff09 1 3相关资料 缩略语 定义 xff08
  • 事件的简单解释:

    事件的简单解释 事件是对象发送的消息 xff0c 以发信号通知操作的发生 操作可能是由用户交互 xff08 例如鼠标单击 xff09 引起的 xff0c 也可能是由某些其他的程序逻辑触发的 引发 xff08 触发 xff09 事件的对象叫做
  • .Net中把图片等文件放入DLL中,并在程序中引用

    摘要 有时我们需要隐藏程序中的一些资源 xff0c 比如游戏 xff0c 过关后才能看到图片 xff0c 那么图片就必须隐藏起来 xff0c 否则不用玩这个游戏就可以看到你的图片了 xff0c 呵呵 本文就讲述了如何把文件 xff08 比如
  • VB中如何保存图片到 Sql Server中,又如何读取出来??

    Const BLOCKSIZE 61 8192 Public Sub SaveToDB ByRef Fld As ADODB Field DiskFile As String Dim byteData As Byte 39 定义数据块数组
  • 在Vf中如何将Excel数据导入(用Vf来导)?

    请大侠们赐教 使用import命令 xff0c 如 xff1a IMPORT FROM 表1 xls TYPE xls 将表1 xls导入为表1 dbf 点击 文件 xff0d gt 导入 xff0d gt 类型选择 xff1a Micro
  • 3.3 生产管理系统需求分析

    根据以上对生产管理内容和生产管理系统的分析 xff0c 一个标准的MRP生产管理系统应该包括如图3 12所示的几大功能 除此之外系统还应包括信息系统必须具备的通用功能 xff0c 例如系统管理 权限设置 数据备份与恢复等 xff0c 这些功
  • Spring源码之事物注解@Transactional原理(源码层面)

    官方文档地址 xff1a https docs spring io spring docs 4 3 21 RELEASE spring framework reference htmlsingle transaction 我翻译的地址 xf
  • 設計公司軟件開發需求分析流程

    工作流程 一 平面设计客户合作流程 信息收集 1 客户提出工作要求 2 客户提供相美文本及图片资料 公司介绍 项目描述 基本设计要求 提案 1 双方就设计内容进行协商 xff0c 修改 补充 xff0c 以达成共识 2双方确定设计具体细节及
  • DBcontext应用于已存在数据库

    EF4 1有三种方式来进行数据操作及持久化 分别是Database First Model First Code first xff0c 前面都已经简单介绍过了 下面简单小结一下 xff1a 1 Database First 是基于已存在的
  • 没有为该对象定义无参数的构造函数(MVC 之DefaultControllerFactory 依赖注入)

    Asp net mvc2中提供很多可以扩展的地方 xff0c 利用这些扩展之后 xff0c asp net mvc使用起来更加灵活 Simone Chiaretta曾写过一篇文章 xff1a 13 ASP NET MVC extensibi
  • Entity Framework 学习总结之一:ADO.NET 实体框架概述

    ADO NET 实体框架概述 新版本中的 ADO NET 以新实体框架为特色 它使开发人员可以通过对象模型 xff08 而不是逻辑 关系数据模型 xff09 专注于数据 实体框架有助于将逻辑数据架构抽象为概念模型 xff0c 并且允许以多种
  • Entity Framework 学习总结之四:对象服务介绍使用

    System Data Objects System Data Entity dll 该命名空间包含一些类 xff0c 用于提供对 对象服务 的核心功能的访问 这些类使您可以藉由作为实体类型实例的强类型 CLR 对象来查询 插入 更新和删除
  • Entity Framework 学习总结之四:对象服务介绍使用

    System Data Objects System Data Entity dll 该命名空间包含一些类 xff0c 用于提供对对象服务的核心功能的访问 这些类使您可以藉由作为实体类型实例的强类型 CLR 对象来查询 插入 更新和删除数据

随机推荐

  • 未执行的URL(MVC异常)

    昨天开始就碰到在IIS里面通过URL无法直接访问到图片 xff0c 提示错误 xff0c 所以经过研究发现 xff0c 合理的配置节应该如下 先改成集成模式 xff0c 然后再改成经典模式 lt system webServer gt lt
  • PIX学习路径-1-选择PIXHAWK作为飞控学习的起点

    xff08 先声明出处 xff1a http blog csdn net qq 21842557 article details 52214425 xff09 创业领域现在最火爆的是什么 xff1f 无疑是机器人和无人机 越来越多的巨头和V
  • PIX学习路径-3-PIXHAWK二次开发之前需要知道的事

    现在作为一个consumer xff0c 能够实现将飞机装配 xff0c 使用MP进行固件烧录 xff0c 初始化校准 xff0c 然后还能够调节PID xff0c 这样算是一个合格的consumer了 xff0c 现在希望对PIXHAWK
  • Java面试题全集(上)

    2013年年底的时候 xff0c 我看到了网上流传的一个叫做 Java面试题大全 的东西 xff0c 认真的阅读了以后发现里面的很多题目是重复且没有价值的题目 xff0c 还有不少的参考答案也是错误的 xff0c 于是我花了半个月时间对这个
  • Netty学习:Channel及其内部接口Unsafe

    连接到网络套接字或组件的一种连接 xff0c 它能够进行I O操作 xff0c 如读 写 连接和绑定 通道为用户提供 通道的当前状态 例如是否打开 它是连接吗 通道的 64 linkplain ChannelConfig配置参数 如接收缓冲
  • 拥抱开源

    使用linux ubuntu 已经一个月多了 xff0c 偶尔用windows是因为要改vb delphi net的程序 在linux下 xff0c 似乎多数软件都是开源的 xff0c 免费的 如今我算是终于义无反顾的走上了这条路了 jav
  • STM32 | C语言对寄存器的封装

    说明 xff1a 这里以GPIO外设为例 xff0c 介绍C语言对寄存器的封装 以此类推其他外设同样可以用这种方法来封装 本文有两部分构成 xff1a 1 介绍宏定义 2 使用结构体封装寄存器列表 1 宏定义 以封装STM32 GPIOH为
  • Intel CPU(i3、i5、i7、i9)型号、性能详细解读

    一 Intel CPU的性能比较 xff1a 它们分为高中低端 xff0c 最低端的G系列 xff0c 然后是低端i3系列 xff0c 中端i5系列 xff0c 高端i7系列和至尊i9系列 Intel CPU 末尾字母含义 xff08 M
  • 字符串搜索函数

    一 字符串中找字符 char strchr const char s int c 表示从左边 开始找这个字符第一次出现的位置 char strrchar const char s int c 表示 从右边 开始找这个字符第一次出现的位置 注
  • 4. Service

    4 Service k8s 中的Pod是朝生夕死的 xff0c 并且是不会重生的 xff0c 尤其是在ReplicaSets中动态创建或销毁Pod 然而每个Pod可以获取自己的IP地址 xff0c 即使这些IP地址是不稳定的 xff08 重
  • STM32 Free RTOS实战

    FreeRTOS是一个开源的实时操作系统 使用的平台 xff1a 秉火STM32 Cortex M3内核开发板 xff0c Free RTOS v8 2 3 多任务流水灯 span class token builtin class nam
  • 参考 | 升级 Win11 移动热点开不了或者开了连不上

    讲道理 就很离谱 一开始我升级了 Win11 后 突然发现 移动热点 开不了了 就是那种 开了之后 手机 ipad 能检测到电脑移动热点的信号 但是会出现这两种情况 死活连不上连上了 在移动端显示 无互联网连接 解决办法 打开 移动热点 打
  • 在 Linux 上安装和使用恶意软件检测工具 LMD

    在 Linux 上安装和使用恶意软件检测工具 LMD xff0c 是个相当简单的过程 xff0c 1 下载资源 wget http www rfxn com downloads maldetect current tar gz 2 解压缩资
  • Docker 使用Dockerfile创建镜像

    基本结构 Dockerfle 由 一行行命令语句组成 xff0c 并且支持以 xff03 开头的注释行 一般而言 xff0c Dockerfle 主体内容分为四部分 xff1a 基础镜像信息 维护者信息 镜像操作指令和容器启动时执行指令 e
  • 为啥我的APP功能引导设计这么low?如何做好功能引导设计?

    功能引导设计历史版本 Level1 APP第一次打开的浏览页 展示主要功能及简单使用方式 xff1b Level2 引导流程页 使用 xff1f 方式在界面右上角 xff0c 点击后展示使用流程详情 xff1b Level3 蒙层 可以有上
  • 【Xshell无法连接虚拟机问题】xshell无法连接虚拟机Ubuntu系统问题

    问题描述 xff1a 电脑新安装虚拟机 xff0c 并且安装Ubuntu系统 xff0c 通过Xshell工具无法连问题 原因是新linux系统未安装 ssh 服务导致 xff0c Xshell连接是依赖 ssh 服务实现的 下面让我们解决
  • [linux下]理解Semaphore及其用法详解

    2009 05 12 13 13 Mutex 是一把钥匙 xff0c 一个人拿了就可进入一个房间 xff0c 出来的时候把钥匙交给队列的第一个 一般的用法是用于串行化对critical section代码的访问 xff0c 保证这段代码不会
  • JavaScript 数据结构——栈

    概念 栈是一种线性结构 xff0c 最大的特点就是先进后出 xff0c 后进先出 入栈push xff1a 出栈pop xff1a 实现 JavaScript中可以用数组表示栈 xff1a span class token keyword
  • Python matplotlib 以pdf形式保存图片

    import matplotlib pyplot as plt from matplotlib backends backend pdf import PdfPages short version plt plot range 10 plt
  • 基于数据报(UDP)编程的接口总结

    文章目录 Udp编程接口socket 创建套接字bind 将套接字绑定到指定的网络地址本机字节序和网络字节序 recvfrom 接收一个数据报并保存源地址 从数据报套接字接收数据调用格式函数功能 sendto 按照指定目的地向数据报套接字发