【问题标题】:Abstracting UDP and TCP send/receive procedures抽象 UDP 和 TCP 发送/接收过程
【发布时间】:2016-02-02 16:52:26
【问题描述】:

美好的一天。

简介。

最近我开始研究一些“低级”网络编程以及 Linux 中的网络协议。为此,我决定创建一个小型网络库。

现在我想知道一些问题。我现在就问其中一个。

如您所知,至少有两种基于 IP 的协议。我谈论TCP和UDP。由于它们的面向连接属性,它们的实现可能在操作系统中有所不同。

根据man 7 udp UDP 套接字上的所有接收操作只返回一个数据包。这是合理的,因为不同的数据报可能来自不同的来源。

另一方面,TCP 连接数据包序列可以被认为是连续的字节流。

现在,关于问题本身。

说,我有一个用于 TCP 连接套接字和 UDP 套接字的 API,例如:

void tcp_connection_recv(endpoint_t *ep, buffer_t *b);
void udp_recv(endpoint_t *ep, buffer_t *b);

endpoint_t 类型将描述端点(远程用于 TCP 连接,本地用于 UDP)。 buffer_t 类型将描述某种基于向量或基于数组的缓冲区。

缓冲区很可能已经由用户分配,我不确定这是否适合 UDP 不更改缓冲区的大小。因此,为了抽象 TCP 和 UDP 操作的代码,我认为它需要根据需要分配尽可能多的缓冲区来包含整个接收到的数据。 此外,为了防止调整用户缓冲区的大小,每个套接字都可以映射到自己的缓冲区(虽然它将是用户空间缓冲区,但它将对用户隐藏)。然后根据用户的请求,数据将从该“内部”缓冲区复制到用户的缓冲区,如果数量不足,则从套接字读取。

有什么建议或意见吗?

【问题讨论】:

  • 你为什么不遵循一些已经存在的实现呢?他们的 API 中加入了很多内容,因此您可以向他们学习。
  • @SergeyA 我确实使用了 Boost 实现,但对我自己的实现非常好奇,因为它对我了解 OSI 模型中应用程序级别以下的协议非常有用。
  • 这很酷。但是您仍然应该研究 API。特别是,您将了解如何处理缓冲区。

标签: c sockets tcp network-programming udp


【解决方案1】:

如果您想创建这样的 API,这将取决于您要提供的服务。在 TCP 中,它与 UDP 不同,因为 TCP 是面向流的。

对于 TCP,tcp_connection_recv 不是重新分配缓冲区,如果用户传递的缓冲区不够大,可以填满整个缓冲区然后返回,可能带有输出参数,并指示还有更多数据等待被阅读。基本上可以使用内核中已经提供的 TCP 连接的接收缓冲区,无需创建其他缓冲区。

对于 udp,您可以向用户请求一个数字,表示它正在等待的最大数据报大小。当您使用 recvfrom 从 UDP 套接字读取数据时,如果您读取的数据少于到达的数据报中的数据,则数据报的其余数据将丢失。您可以先读取 MSG_PEEK 标志,以了解有多少数据可用。

一般来说,我不会处理应用程序的缓冲区,因为应用程序,实际上是应用程序层协议,是一个知道它期望如何接收数据的协议。

【讨论】:

  • 如何使用SIOCINQioctl 找出第一个数据报长度?
  • @SergeyKanaev,你是对的,只要考虑man7.org/linux/man-pages/man7/udp.7.html中的相应评论
  • 也许您对send API 也有任何建议?
  • @SergeyKanaev,发送应该更容易,因为开发人员知道他们想要发送什么。所以端点和缓冲区,包括缓冲区长度,应该没问题。
猜你喜欢
  • 2018-05-08
  • 1970-01-01
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 2017-02-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多