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

这篇具有很好参考价值的文章主要介绍了【计算机网络】网络编程接口 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  */
    }
}

     下一篇 【计算机网络】网络编程接口 Socket API 解读(11)文章来源地址https://www.toymoban.com/news/detail-713524.html

到了这里,关于【计算机网络】网络编程接口 Socket API 解读(10)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

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

             Socket 是网络协议栈暴露给编程人员的 API,相比复杂的计算机网络协议,API 对关键操作和配置数据进行了抽象,简化了程序编程。         本文讲述的 socket 内容源自 Linux man。本文主要对各 API 进行详细介绍,从而更好的理解 socket 编程。 poll()           遵

    2024年02月09日
    浏览(31)
  • 【计算机网络】网络编程接口 Socket API 解读(5)

             Socket 是网络协议栈暴露给编程人员的 API,相比复杂的计算机网络协议,API 对关键操作和配置数据进行了抽象,简化了程序编程。         本文讲述的 socket 内容源自 Linux man。本文主要对各 API 进行详细介绍,从而更好的理解 socket 编程。 connect()         

    2024年02月08日
    浏览(30)
  • 【计算机网络】网络编程接口 Socket API 解读(8)

             Socket 是网络协议栈暴露给编程人员的 API,相比复杂的计算机网络协议,API 对关键操作和配置数据进行了抽象,简化了程序编程。         本文讲述的 socket 内容源自 Linux man。本文主要对各 API 进行详细介绍,从而更好的理解 socket 编程。        本文主要描述

    2024年02月08日
    浏览(32)
  • 【计算机网络】网络编程接口 Socket API 解读(6)

             Socket 是网络协议栈暴露给编程人员的 API,相比复杂的计算机网络协议,API 对关键操作和配置数据进行了抽象,简化了程序编程。         本文讲述的 socket 内容源自 Linux man。本文主要对各 API 进行详细介绍,从而更好的理解 socket 编程。 recv()           遵

    2024年02月07日
    浏览(29)
  • 【计算机网络】网络编程接口 Socket API 解读(1)

             Socket 是网络协议栈暴露给编程人员的 API,相比复杂的计算机网络协议,API 对关键操作和配置数据进行了抽象,简化了程序编程。         本文讲述的 socket 内容源自 Linux man。本文主要对各 API 进行详细介绍,从而更好的理解 socket 编程。 遵循 POSIX.1 - 2001、POS

    2024年02月09日
    浏览(28)
  • 计算机网络--网络编程(1)

    简单认识一下传输层中的UDP和TCP: TCP:有链接,可靠传输,面向字节流,全双工 UDP:无连接,不可靠传输,面向数据报,全双工 有链接类似于打电话,通了就是有链接。没通就一直在等待。 无连接类似于发短信,只管发,不管到。 可靠传输就是保证信息传输的可靠性。就

    2024年02月11日
    浏览(29)
  • 【计算机网络】4 Socket网络编程

    目录 写在前面的话 概览 环境 URL请求程序: 2. 系统时间查询 服务端 T_TCPServer.py代码 客户端 T_TCPClient.py代码 运行效果 3. 网络文件传输 服务端 TF_TCPServer.py代码 运行效果(后面加了远程功能,效果图暂时还在本地) 4. 网络聊天室 服务端 UDPServer.py代码 客户端 UDPClient.py代码 运

    2024年02月01日
    浏览(31)
  • 【计算机网络】网络编程套接字(二)

    简单TCP服务器实现 我们将会使用到的头文件放在 comm.h 文件中 创建套接字 创建过程和UDP服务器几乎完全一样,除了使用的是TCP服务器使用的是流式服务(SOCK_STREAM),UDP使用的是数据包服务(SOCK_DGRAM) 服务器绑定 绑定的过程和UDP服务器也是相同的,可以看着复习一下 定义好 st

    2024年02月13日
    浏览(35)
  • 计算机网络---网络编程套接字(一)

    ✨ 计算机网络—网络编程套接字之UDP数据报套接字编程 作者介绍: 🎓作者:偷偷敲代码的青花瓷🐱‍🚀 👀作者的Gitee:代码仓库 📌系列文章推荐:计算机网络 ——网络原理之初识 ✨✨我和大家一样都是热爱编程✨,很高兴能在此和大家分享知识,希望在分享知识的同时,能和大

    2023年04月09日
    浏览(28)
  • 【计算机网络】网络编程套接字(一)

    目录 1.预备知识 1.1.理解源IP地址和目的IP地址 1.2.认识端口号 1.2.1.理解\\\"端口号\\\"和\\\"进程ID\\\" 1.2.2.理解源端口号和目的端口号 1.3.认识TCP/UDP协议 1.3.1.TCP协议 1.3.2.UDP协议 1.4.网络字节序 网络字节序和主机字节序的转换 2.socket编程接口 2.1.sockaddr结构 struct sockaddr_in 的具体结构: 2.

    2024年02月08日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包