【计算机网络】网络编程接口 Socket API 解读(10)

         Socket 是网络协议栈暴露给编程人员的 API,相比复杂的计算机网络协议,API 对关键操作和配置数据进行了抽象,简化了程序编程。

        本文讲述的 socket 内容源自 Linux man。本文主要对各 API 进行详细介绍,从而更好的理解 socket 编程。


udp(7)

1.库

标准 c 库,libc, -lc

2.头文件

<sys/socket.h>

3.接口定义

       #include <sys/socket.h>#include <netinet/in.h>#include <netinet/udp.h>udp_socket = socket(AF_INET, SOCK_DGRAM, 0);

4.接口描述

        这个是 RFC 768 中描述的 UDP 的实现,它实现了无连接、不可靠数据包服务。数据包可能会在到达前重新排序或者重复,UDP 通过发送端生成、接收端检查校验和来捕捉传输错误。

        当 UDP 套接字创建好后,其本地地址和对端地址还没有指定,这时就可以通过 sendto(2) 或者 sendmsg(2) 发送报文,只要携带一个有效的目的地址即可。如果在该套接字上使用 connect(2) ,那么会设置默认目的地址,可以通过 send(2) 或者 write(2) 发送报文,这时不用指定地址了。同时,还是可以通过 sendto(2) 或者 sendmsg(2) 发送到其他地址。为了接收数据报文,套接字可以先通过 bind(2) 绑定到本地地址,否则套接字层会自动从 /proc/sys/net/ipv4/ip_local_port_range 中自动分配一个端口并将地址指定为 INADDR_ANY。

        所有接收操作只返回一个报文,当报文小于几首缓冲区时,会返回报文大小,而当缓冲区小时,会发生截断并设置 MSG_TRUNC 标记。不支持 MSG_WAITALLL 标记。

        IP 选项可以通过 ip(7) 中讲的套接字选项来收发,只有在 /proc/ 中对应的参数使能时才会被内核处理。(关闭时也会传递给用户)。参考 ip(7)

        在发送时入股设置了 MSG_DONTROUTE 标记,目标地址必须指定为一个本地接口地址,数据包也是发给对应接口的。

        默认情况下,Linux UDP 进行路径 MTU(最大传输单元) 发现,这意味着内核会持续跟踪指定目标 IP 地址上的 MTU,一旦写超过就会返回 EMSGSIZE 错误。这种情况下,应用应该减少数据包大小。路径 MTU 发现可以通过 /proc/sys/net/ipv4/ip_no_pmtu_disc 文件或者 IP_MTU_DISCOVER 套接字选项关闭。参考 ip(7) 查看更多信息。关闭后,UDP 会对超过接口 MTU 的 UDP 包进行分片。但是,从应性能或者可靠性方面考虑,不建议关闭它。

地址格式

        UDP 使用 IPv4 sockaddr_in 地址格式,在 ip(7) 中描述。

错误处理

        所有严重错误都会通过错误返回传递给用户,即使套接字还没有连接,这些包括从网络上接收到的异步错误。我们也可能会收到套接字上之前发送数据包导致的错误。这个行为和其他 BSD 实现不太一样,其他在连接前是不会传递任何错误的。Linux 行为在 RFC 1122 中管理。

        为了和之前的代码兼容,Linux 2.0 和 2.2 中可以通过 SO_BSDCOMPAT SOl_SOCKET 选项在套接字连接后接收对端错误(除了 EPROTO 和 EMSGSIZE)。本地生成的错误总是会传递给用户的。后面这个选项就被删除了。参考 socket(7) 查阅更多信息。

        当 IP_RECVERR 选项开启时,所有错误都被存储到套接字错误队列中,可以同 recvmsg(2) 通过 MSG_ERRQUEQUE 标记来获取。

/proc 接口

        系统级的 UDP 参数可以通过 /proc/sys/net/ipv4/ 文件来访问:

        udp_mem(Linux 2.6.25)

        这个三元向量整数控制着所有 UDP 套接字可以排队的页数

        min        比这个页数低时,UDP 不会收到干扰;当 UDP 分配的内容超过这个值时,UDP 开始调节内存使用

        pressure        这个数值在 tcp_mem 引入并进行介绍,参考 tcp(7)

        max        所有 UDP  套接字允许排队的最大页数

        udp_rmem_min(整数,默认值:页大小,Linux 2.6.25 后)

        UDP 接收缓冲区调整中的最小值(字节数)。每个套接字可以使用这个大小来接收数据,即使 UDP 套接字总页数超过了 udp_mem pressure。

        udp_wmem_min(整数,默认值:页大小,Linux 2.6.25 后)

        UDP 发送缓冲区调整中的最小值(字节数),同样即使 UDP 套接字总页数超过了 udp_mem pressure,每个套接字仍然可以使用这个值来发送数据。

套接字选项

        为了设置或者获取套接字选项,可以通过 getsockopt(2) 来读取或者 setsockopt(2) 来设置 UDP 选项,选项级别设置为 IPPROTO_UDP。除非特别备注,否则 optval 是一个指向整型数的指针。

        下面时一系列 UDP 相关的套接字选项。套接字其他更多详细选项,也适用于 UDP,参考 socket(7)。

        UDP_CORK(Linux 2.5.44 后)

        如果这个选项开启,所有发送数据会累计到一个数据报文再发送,否则会单独发送。这个选项在考虑到可移植性时不建议使用。

        UDP_SEGMENT(Linux 4.18)

        开启 UDP 分片降负载。这个选项能够降低 send(2) 的耗时,通过将多个发送报文在内核最后发出前合并为一个大的数据包,即便超出 MTU。这个功能更倾向于通过硬件实现,也可以通过软件实现。这个选项携带 [0, USHRT_MAX] 中的一个值来设置分片大小:数据报载荷,不包含 UDP 头。

        UDP_GRO(Linux 5.0 后)

        开启 UDP 接收降负载。如果开启这个选项,套接字可以接收等效多个数据报文的数据缓冲区,并通过 cmsg(3) 携带分段大小。这个选项是分片降负载的反过程。他能在内核接收路径上通过讲多个数据报等效于一个大数据包来降低耗时。这个选项不应该在移植场景下使用。

Ioctls

        可以通过 ioctl(2) 来访问这些 ioctls,对应的语法为:

        

              int value;error = ioctl(udp_socket, ioctl_type, &value);

        FIONREAD(SIOCINQ)

        获取一个整型数据指针:返回下一个等待报文的整型大小或者没有等待报文时返回 0。警告:使用 FIONREAD 时无法区分没有等待报文和等待报文长度为 0 情况。这种情况下,使用 select(2)、poll(2)、epoll(7) 区分更安全。

        TIOCOUTQ(SIOCOUTQ)

        返回本地发送队列上的数据数量,Linux 2.4 后支持。

此外,所有 ip(7) 和 socket(7) 中描述的 Ioctls 都支持。 

5.返回值

       所有 socket(7) 和 ip(7) 中定义的错误码都可能在 UDP 套接字的发送和接收函数返回。

        ECONNREFUSED

        目的地址没有关联的接收者。这个可能由之前套接字上发送的数据包导致的。 

6.示例代码

        下面是一个 getsockopt 函数的使用代码:

int rc;
int s;
int option_value;
int option_len;
struct linger l;
int getsockopt(int s, int level, int option_name,
char *option_value,int *option_len);⋮
/* Is out-of-band data in the normal input queue? */
option_len = sizeof(int);
rc = getsockopt(s, SOL_SOCKET, SO_OOBINLINE, (
char *) &option_value, &option_len);
if (rc == 0)
{if (option_len == sizeof(int)){if (option_value)/* yes it is in the normal queue */else/* no it is not*/}
}⋮
/* Do I linger on close? */
option_len = sizeof(l);
rc = getsockopt(s, SOL_SOCKET, SO_LINGER, (char *) &l, &option_len);
if (rc == 0)
{if (option_len == sizeof(l)){if (l.l_onoff)/* yes I linger */else/* no I do not  */}
}

     

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

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

相关文章

linux 服务器类型Apache配置https访问

一&#xff1a;查看服务器类型&#xff0c;下载相应的SSL证书 命令&#xff1a;netstat -anp | grep :80 httpd是Apache超文本传输协议(HTTP)服务器的主程序&#xff0c;所以下载Apache证书 二&#xff1a;将证书解压后复制到服务器上 三个文件&#xff1a;xxx.key xxx_publ…

C //例6.8 输入一行字符,统计其中有多少个单词,单词之间用空格分隔开。

C语言设计 &#xff08;第四版&#xff09; 谭浩强 例6.8 例6.8 输入一行字符&#xff0c;统计其中有多少个单词&#xff0c;单词之间用空格分隔开。 IDE工具&#xff1a;VS2010 Note: 使用不同的IDE工具可能有部分差异。 代码块 方法1&#xff1a;使用gets函数 #include …

草莓病害图像数据集(YOLO使用,train为655张照片和val为487张照片)

前言&#xff1a;所有图像和标签是一一对应&#xff0c;没有标签缺失 写了两个程序来分别检查train文件夹的图像和val文件夹图像是否有缺失标签&#xff0c;如果有&#xff0c;会直接打印出缺失标签的图像名字。也方便以后用户自己添加自己收集的图像数据后&#xff0c;核对图…

Linux shell编程学习笔记12:布尔运算和逻辑运算

Linux Shell 脚本编程和其他编程语言一样&#xff0c;支持算数、关系、布尔、逻辑、字符串、文件测试等多种运算。前面几节我们陆续研究了 Linux shell编程 中的 字符串运算、算术运算和关系运算&#xff0c;今天我们来研究 Linux shell编程中的的布尔运算、逻辑运算。 一、…

React实现地图搜索

在现代的Web应用程序中&#xff0c;地图搜索功能对于许多应用来说是必不可少的。无论是为了查找特定位置、规划路线&#xff0c;还是为了展示附近的兴趣点&#xff0c;地图搜索都可以提供给用户很好的交互体验。 在本文中&#xff0c;我们将使用React框架来实现一个简单的地图…

纯文本邮件发送:java

1.打开jdk的conf下的security文件的.security,找到并删除&#xff0c;权限问题建议复制文件修改后替换 jdk.tls.disabledAlgorithmsSSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \ DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL 删除后的内容 然…

数据结构 - 4(栈和队列6000字详解)

一&#xff1a;栈 1.1 栈的概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原…

php如何查找地图距离

要在PHP中使用高德地图、百度地图或腾讯地图获取位置信息&#xff0c;您可以使用它们的相应API服务。以下是获取位置信息的一般步骤&#xff1a; 思路: 获取API密钥&#xff1a;首先&#xff0c;您需要注册并获取相应地图服务提供商的API密钥。这将允许您访问他们的API以获取位…

Python学习基础笔记六十九——文本2

二进制&#xff08;字节&#xff09;模式&#xff1a; 文本文件&#xff0c;纯文本文件就是保存文本字符串的文件&#xff0c;跟word还不一样&#xff0c;word是富文本文件。 其实就文件存储的底层来说&#xff0c;不管什么类型的文件&#xff08;文本、视频、图片、word、Ex…

rsync 备份工具(附rsync+inotify 实时同步部署实例)

rsync 备份工具(附rsyncinotify 实时同步部署实例&#xff09; 1、rsync概述1.1关于rsync1.2rsync 的特点1.3工作原理 2、rsync相关命令2.1基本格式和常用选项2.2启动和关闭rsync服务2.3下行同步基本格式2.4上行同步基本格式2.5免交互2.5.1指定密码文件2.5.2rsync-daemon方式2.…

博弈论:gym104065j

https://vjudge.net/contest/587311#problem/J 我也不知道我在此题中学到了什么套路 结论&#xff1a;你选的数必须尽量接近 s u m 3 \frac {sum} 3 3sum​&#xff0c;然后这个就是解 因为另外两人选的是和你的数相比不可能更接近&#xff0c;所以必然一个大一个小 唯一的…

2.9 深入GPU硬件架构及运行机制

五、GPU技术要点 1.SMID和SIMT SIMD&#xff08;Single Instruction Multiple Data&#xff09;是单指令多数据&#xff0c;在GPU的ALU&#xff08;在Core内&#xff09;单元内&#xff0c;一条指令可以处理多维向量&#xff08;一般是4D&#xff09;的数据。比如&#xff0c…

sklearn 机器学习基本用法

# # 科学计算模块 # import numpy as np # import pandas as pd # # 绘图模块 # import matplotlib as mpl # import matplotlib.pyplot as plt # from sklearn.linear_model import LinearRegression # from sklearn import datasets # from sklearn.model_selection import t…

宅在家里也能干的副业,每天挣60—300元,人人可做

想在家搞副业&#xff0c;每天挣60-300元&#xff0c;大家觉得难吗&#xff1f;我告诉你&#xff0c;一点也不难。找对路子&#xff0c;足不出户也能搞钱。今天我就给大家分享一下三个网上靠谱的副业&#xff0c;门槛低上手快&#xff0c;只需一部手机&#xff0c;每天利用碎片…

Hazelcast系列(三):hazelcast集成(服务器/客户端)

系列文章 Hazelcast系列(一)&#xff1a;初识hazelcast Hazelcast系列(二)&#xff1a;hazelcast集成&#xff08;嵌入式&#xff09; Hazelcast系列(三)&#xff1a;hazelcast集成&#xff08;服务器/客户端&#xff09; Hazelcast系列(四)&#xff1a;hazelcast管理中心 …

动态规划:918. 环形子数组的最大和

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》《算法》 文章目录 前言一、题目解析二、解题思路解题思路状态表示状态转移方程初始化填表顺序返回值 三、代码实现总结 前言 本篇文章仅是作为小白的我的一些理解&#xff0c;&#xff0c;…

docker安装skyWalking笔记

确保安装了docker和docker-compose sudo docker -v Docker version 20.10.12, build 20.10.12-0ubuntu4 sudo docker-compose -v docker-compose version 1.29.2, build unknown 编写docker-compose.yml version: "3.1" services: skywalking-oap:image: apach…

ELF和静态链接:为什么程序无法同时在Linux和Windows下运行?

目录 疑问 编译、链接和装载&#xff1a;拆解程序执行 ELF 格式和链接&#xff1a;理解链接过程 小结 疑问 既然我们的程序最终都被变成了一条条机器码去执行&#xff0c;那为什么同一个程序&#xff0c;在同一台计算机上&#xff0c;在 Linux 下可以运行&#xff0c;而在…

《机器学习》第5章 神经网络

文章目录 5.1 神经元模型5.2 感知机与多层网络5.3 误差逆传播算法5.4 全局最小与局部最小5.5 其他常见神经网络RBF网络ART网络SOM网络级联相关网络Elman网络Boltzmann机 5.6 深度学习 5.1 神经元模型 神经网络是由具有适应性的简单单元组成的广泛并行互连的网络&#xff0c;它…

sql 注入(1), union 联合注入

sql 注入, union 联合注入 一, 参数分类 根据可控参数的类型不同, 对注入类型分类: 1. 数字型select * from table where id1 2. 字符型select * from table where usernameroot 3. 搜索型select * from table where id like %root% 4. 关于注释:注入时, 在查询参数中使用注…