socket编程-UDP各函数及其用法

news2024/11/24 15:49:00

socket编程-UDP


socket主要类型

流套接字(SOCK_STREAM)

流套接字用于提供面向连接、可靠的数据传输服务。该服务将保证数据能够实现无差错、无重复送,并按顺序接收。流套接字之所以能够实现可靠的数据服务,原因在于其使用了传输控制协议,即TCP协议。

数据报套接字(SOCK_DGRAM)

数据报套接字提供一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用UDP协议进行数据的传输。由于数据报套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在应用层中做相应的处理。

原始套接字(SOCK_RAW)

原始套接字与标准套接字(标准套接字指的是前面介绍的流套接字和数据报套接字)的区别在于:原始套接字可以读写内核没有处理的IP数据包,而流套接字只能读取TCP协议的数据,数据报套接字只能读取UDP协议的数据。因此,如果要访问其他协议发送的数据必须使用原始套接。

实际应用中,数据报socket的应用场景比较少

流套接字(SOCK_STREAM)

在这里插入图片描述

socket函数:socket函数用于创建一个新的socket,也就是向系统申请一个socket资源,socket函数用户客户端和服务端。socket()函数的返回值其本质是一个文件描述符,是一个整数。一般情况下,socket创建都会成功,除非系统资源耗尽,socket函数一般不会返回失败(-1)。其函数声明如下:

int socket(int domain, int type, int protocol);
  1. domain
     协议域,又称协议族(family)。常用的协议族有AF_INET、AF_INET6、AF_LOCAL(或称AF_UNIX,Unix域Socket)、AF_ROUTE等。协议族决定了socket的地址类型,在通信中必须采用对应的地址 ,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地址。

  2. type
     指定socket类型。常用的socket类型有SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等。流式socket(SOCK_STREAM)是一种面向连接的socket,针对于面向连接的TCP服务应用。数据报式socket(SOCK_DGRAM)是一种无连接的socket,对应于无连接的UDP服务应用。

  3. protocol
     指定协议。常用协议有IPPROTO_TCP、IPPROTO_UDP、IPPROTO_STCP、IPPROTO_TIPC等,分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。

示例代码如下:

	//1.创建套接字
    int ServerSockFd;
    if((ServerSockFd=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))==-1)//socket创建失败
    {
        perror("socket 创建失败");
        return -1;
    }

sockaddr结构体与sockaddr_in结构体:

sockaddr在头文件#include <sys/socket.h>中定义,sockaddr的缺陷是:sa_data把目标地址和端口信息混在一起了,如下:

struct sockaddr {  
     sa_family_t sin_family;//地址族
    char sa_data[14]; //14字节,包含套接字中的目标地址和端口信息               
   };

sockaddr_in在头文件#include<netinet/in.h>或#include <arpa/inet.h>中定义,该结构体解决了sockaddr的缺陷,把port和addr 分开储存在两个变量中,如下:

/* Structure describing an Internet socket address.  */
struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port;			/* Port number.  */
    struct in_addr sin_addr;		/* Internet address.  */
 
    /* Pad to size of `struct sockaddr'.  */
    unsigned char sin_zero[sizeof (struct sockaddr)
			   - __SOCKADDR_COMMON_SIZE
			   - sizeof (in_port_t)
			   - sizeof (struct in_addr)];
  };
  1. 二者长度一样,都是16个字节,即占用的内存大小是一致的,因此可以互相转化。二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。
  2. sockaddr常用于bind、connect、recvfrom、sendto等函数的参数,指明地址信息,是一种通用的套接字地址。
  3. sockaddr_in 是internet环境下套接字的地址形式。所以在网络编程中我们会对sockaddr_in结构体进行操作,使用sockaddr_in来建立所需的信息,最后使用类型转化就可以了。一般先把sockaddr_in变量赋值后,强制类型转换后传入用sockaddr做参数的函数:sockaddr_in用于socket定义和赋值;sockaddr用于函数参数。

两个函数 htons() 和 inet_addr()。

  1. htons()作用是将端口号由主机字节序转换为网络字节序的整数值。(host to net)
  2. inet_addr()作用是将一个IP字符串转化为一个网络字节序的整数值,用于sockaddr_in.sin_addr.s_addr。
  3. inet_ntoa()作用是将一个sin_addr结构体输出成IP字符串(network to ascii)。
  4. htonl()将u_long从主机转换为 TCP/IP 网络字节顺序 (,这是大端)
  5. 已服务端为例进行演示
	//2.进行绑定,指定用于通信的ip地址和端口
    struct sockaddr_in ServerAddr;//服务端地址信息数据结构
    //将协议簇指定为ipv4
    ServerAddr.sin_family=AF_INET;
    //服务端程序绑定本主机的任意IP地址
    ServerAddr.sin_addr.s_addr=htonl(INADDR_ANY);
    服务端程序绑定指定ip
    //ServerAddr.sin_addr.s_addr=inet_addr("127.0.0.1");
    ServerAddr.sin_port=htons(9000);

bind函数:服务端把用于通信的地址和端口绑定到socket上。如果绑定的地址错误,或端口已被占用,bind函数一定会报错,否则一般不会返回错误。如无错误发生,则bind()返回0。否则的话,将返回-1。其函数声明如下:

int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
  1. 参数sockfd,需要绑定的socket,是一个文件描述符。
  2. 参数addr,存放了服务端用于通信的地址和端口,用结构体sockaddr_in强制转换得到。
  3. 参数addrlen,表示addr结构体的大小。
  4. 返回值:成功则返回0,失败返回-1,错误原因存于errno 中。

示例代码如下:

	if(bind(ServerSockFd,(sockaddr*)&ServerAddr,sizeof(ServerAddr))!=0)
    {
        perror("bind failed");
        close(ServerSockFd);
        return -1;
    }

sendto函数:指向一指定目的地发送数据,SendTo()适用于发送未建立连接的UDP数据包 (参数为SOCK_DGRAM)。如无错误发生,则返回发送数据的字符数。否则的话,将返回-1。其函数声明如下:

ssize_t sendto(int sockfd,const void *buf,
                 size_t nbytes,int flags,
                 const struct sockaddr *to,        
                 socklen_t addrlen);
  1. 参数sockfd,需要绑定的socket,是一个文件描述符。
  2. buf: 发送数据缓冲区
  3. nbytes: 发送数据缓冲区的大小
  4. flags:一般为0
  5. to: 指向目的主机地址结构体的指针
  6. addrlen:to所指向内容的长度

示例代码如下:

	if((ret=sendto(ClientSockFd, sen, sizeof(sen), 0, (sockaddr*)&ServerAddr, sizeof(ServerAddr)))<=0)
        {
            std::cout<<"send ret="<<ret<<std::endl;
            break;
        }
        std::cout<<"客户端发送:"<<rec<<std::endl;
        std::cout<<"send ret="<<ret<<std::endl;

recvfrom 函数:接收数据报,并存储源地址。如无错误发生,则返回接收到的字符数。否则的话,将返回-1。其函数声明如下:

ssize_t recvfrom(int sockfd, void *buf,
					size_t nbytes,int flags,
					struct sockaddr *from,
            		socklen_t *addrlen);
  1. 参数sockfd,需要绑定的socket,是一个文件描述符。
  2. buf: 发送数据缓冲区
  3. nbytes: 发送数据缓冲区的大小
  4. flags:一般为0
  5. from: 源地址结构体指针,用来保存数据的来源
  6. addrlen: from所指内容的长度

示例代码如下:

	 //recv接收函数,失败返回-1
     if((ret=recvfrom(ClientSockFd, rec, sizeof(rec), 0, (sockaddr*)&ClientAddr, (socklen_t*)&len))<=0)
     {
         std::cout<<"recv ret="<<ret<<std::endl;
         break;
     }

     std::cout<<"客户端接收:"<<rec<<std::endl;
     std::cout<<"recv ret="<<ret<<std::endl;

最后完整简易服务端代码:https://blog.csdn.net/weixin_45256307/article/details/129458811

最后完整简易客户端代码:https://blog.csdn.net/weixin_45256307/article/details/129458814

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

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

相关文章

电商API分享:获得淘宝商品评论、商品评论问答列表 分页显示 代码展示

item_review-获得淘宝商品评论item_question_answer-淘宝评论问答列表接口请求示例<?php// 请求示例 url 默认请求参数已经URL编码处理 // 本示例代码未加密secret参数明文传输&#xff0c;若要加密请参考&#xff1a;https://open.qq1635608656.cn/help/demo/sdk/demo-sig…

关于IDEA系列行号左侧空白处太宽的缩短

IntelliJ IDEA行号左侧空白处太宽&#xff0c;缩短的方法修改之前打开设置File–Settings–Editor–General–Gutter Icons&#xff08;可以在Settings左上角搜索框直接搜Gutter Icons&#xff09;将对号去掉就好了 &#xff0c;但是这些符号今后不会显示 &#xff0c;最重要的…

【数据结构】单链表中,如何实现 将链表中所有结点的链接方向“原地”逆转

一.实现一个单链表&#xff08;无头单向不循环&#xff09; 我们首先实现一个无头单向不循环单链表。 写出基本的增删查改功能&#xff0c;以及其它的一些功能&#xff08;可忽略&#xff09;。 #include<stdio.h> #include<assert.h> #include<stdlib.h>…

ros使用详解

文章目录ros概述ros使用winbox登录ros关机重启ros修改路由器名ros恢复出厂设置ros修改管理员账号密码及限制登录IPros备份还原ros使用pppor拨号ros的nat&#xff0c;也叫伪装ros静态ARP绑定ros端口映射ros配置静态路由ros概述 软路由是指利用台式机或服务器的供应商配合一定软…

mos管驱动与米勒平台介绍、消除

mos驱动设计 1.选择适当的驱动芯片 为了控制MOSFET&#xff0c;需要使用专门的驱动芯片。选择合适的芯片需要考虑MOSFET的电压和电流需求。常见的驱动芯片包括IR2110、IR2184、MIC4424等。 2.设计电路 在驱动电路中&#xff0c;需要加入一些电路元件来保证MOSFET的顺畅工作…

爱国者一体机电脑蓝屏怎么U盘重装系统教学?

爱国者一体机电脑蓝屏怎么U盘重装系统教学&#xff1f;有用户使用的爱国者一体机电脑开机了之后突然变成了蓝屏的了。而且无法继续使用了&#xff0c;那么遇到这样的蓝屏问题怎么去进行系统的重装呢&#xff1f;一起来看看以下的U盘重装系统教学吧。 准备工作&#xff1a; 1、U…

es6动态模块import()

目录 一、语法说明 二、适用场合 三、注意点 四、示例代码 五、效果 一、语法说明 import命令会被 JavaScript 引擎静态分析&#xff0c;先于模块内的其他语句执行&#xff08;import命令叫做“连接” binding 其实更合适&#xff09;。 // 报错 if (x 2) {import MyMod…

网络安全工程师在面试安全岗位时,哪些内容是加分项?

金三银四已经来了&#xff0c;很多小伙伴都在困惑&#xff0c;面试网络安全工程师的时候&#xff0c;有哪些技能是加分项呢&#xff1f;接下来&#xff0c;我简单说说&#xff01; 去年我在微博上贴了一些在面试安全工作时会加分的内容&#xff0c;如下&#xff1a; 1. wooyu…

MySQL、HBase、ElasticSearch三者对比

1、概念介绍 MySQL&#xff1a;关系型数据库&#xff0c;主要面向OLTP&#xff0c;支持事务&#xff0c;支持二级索引&#xff0c;支持sql&#xff0c;支持主从、Group Replication架构模型&#xff08;本文全部以Innodb为例&#xff0c;不涉及别的存储引擎&#xff09;。 HBas…

【AI JUST AI】自然语言交互式学习,ChatGPT成了我的最佳博客写作助手

【AI JUST AI】自然语言交互式学习&#xff0c;ChatGPT成了我的最佳博客写作助手什么是自然语言交互式学习&#xff1f;ChatGPT是如何成为我的最佳博客写作助手的&#xff1f;**把与Chat GPT的每一次对话都当作一种类型的非系统学习**有问必答&#xff0c;随时交互总结后记——…

【Python】案例介绍Pytest进行压力测试

在现代Web应用程序中&#xff0c;性能是至关重要的。为了确保应用程序能够在高负载下正常运行&#xff0c;我们需要进行性能测试。 今天&#xff0c;应小伙伴的提问&#xff0c; 田辛老师来写一个Pytest进行压力测试的简单案例。 这个案例的测试网站我们就隐藏了&#xff0c;不…

Windows 10 - Python 消息队列 RabbitMQ 学习总结 1

目录消息队列的基本知识概述什么是消息队列&#xff1f;为何要使用消息队列的原因&#xff1f;理解消息队列服务器和 Web 服务器的关系题外&#xff1a;关于服务端和客户端的企业级理解了解 Web 服务器了解 Web 框架和 Web 服务的区别对于框架和服务器B/S架构消息队列的个人理解…

PMP项目管理项目风险管理

目录1 项目风险管理概述2 规划风险管理3 识别风险4 实施定性风险分析5 实施定量风险分析6 规划风险应对7 实施风险应对8 监督风险1 项目风险管理概述 项目风险管理的目标在于提高正面风险的概率和&#xff08;或&#xff09;影响&#xff0c;降低负面风险的概率和&#xff08;…

STM32CubeIDE 快速开发入门指南

描述 STM32CubeIDE是一体式多操作系统开发工具&#xff0c;是STM32Cube软件生态系统的一部分。 STM32CubeIDE是一种高级C/C开发平台&#xff0c;具有STM32微控制器和微处理器的外设配置、代码生成、代码编译和调试功能。它基于Eclipse/CDT™框架和用于开发的GCC工具链&#xf…

CentOS7部署Doris V1.2.2

一、环境准备 服务器信息 IP配置部署内容192.168.43.1508核8GFE&#xff0c;BE192.168.43.1514核8GBE192.168.43.1524核8GBE 安装前置条件 服务器配置免密登录 3台服务器配置免密登录&#xff0c;可参考CentOS7 设置SSH免密钥登陆 安装JDK 安装JDK 修改CentOS系统默认参…

【opensea】opensea-js 升级导致的问题,及解决笔记

opensea 协议升级导致旧包不能使用了 我使用的是 “opensea-js”: "^4.0.12” 版本当SDK。于2023年3月9日之后&#xff0c;不能使用了&#xff0c;需要升级到 Seaport v1.4 协议的包。 报错如下: Error: API Error 400: Please provide an OPEN order type when using …

第N次重装系统之Ubtntu

前言又一次换了服务器&#xff0c;由于centOS已经完成了自己的生命周期&#xff0c;接下来我会转去使用Ubtntu系统。当然&#xff0c;大部分docker命令是不会收到影响的&#xff0c;但是一部分安装过程可能就要重新学习了。其实这个系统也有自己的老牌包管理器apt&#xff0c;所…

ESP32设备驱动-TCS3200颜色传感器驱动

TCS3200颜色传感器驱动 1、TCS3200介绍 TCS3200 和 TCS3210 可编程彩色光频率转换器在单个单片 CMOS 集成电路上结合了可配置的硅光电二极管和电流频率转换器。 输出是方波(50% 占空比),其频率与光强度(辐照度)成正比。 满量程输出频率可以通过两个控制输入引脚按三个预…

关系抽取方面的基础

关系抽取方面的基础一、基本概念1. 什么是关系抽取&#xff08;Relation Extraction&#xff0c;RE&#xff09;&#xff1f;2. 都有什么奇怪的关系&#xff1f;3. 任务评价指标二、 关系抽取方法2.1 按模型结构分——Pipeline 和 Joint方法Pipeline方法Joint方法2.2 按解码方式…

RK3588平台开发系列讲解(同步与互斥篇)信号量介绍

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、信号量介绍二、信号量API1、结构体2、API三、函数调用流程沉淀、分享、成长,让自己和他人都能有所收获!😄 📢上一章我们看了自旋锁的原理,本章我们一起学习下信号量的用法。 一、信号量介绍 和自旋锁一样,…