0

我是一位经验丰富的网络程序员,面临需要一些建议的情况。

我需要在几个传出接口上分发一些数据(通过不同的 tcp 套接字连接,每个连接对应于每个接口)。但是,重要的部分是,我应该能够在具有更好带宽的接口上发送更多/大部分数据,即可以更快发送的数据。

我的意见是为此目的使用select api(unix和windows)。我过去使用过 select、poll 甚至 epoll。但只要数据可用,它总是用于从多个套接字读取。

在这里,我打算按顺序在几个接口上写入连续的数据包,然后监视每个接口的写入描述符(选择参数),然后哪个可用(意味着它能够先发送数据包),我将继续发送更多数据包通过那个描述符。

我能在这里实现我的意图吗?即,如果我有一个 10Mbps 链路的接口与另一个 1Mbps 链路的接口,我希望能够通过更快的接口获取大部分数据包。

更新 1:我想知道在这种情况下 select 的行为是什么,即当您在读取描述符上调用 select 时,会返回数据可用的那个。但是,在我的场景中,当我们在描述符上写入并等待 select 返回首先完成写入的描述符时,select 是否确保仅在写入整个数据包时才返回,即说我尝试一次写入 1200 个字节。它只会在全部 1200 都返回或出现永久性错误时返回吗?我不确定 select 会如何表现,也没有找到任何描述它的文档。

4

2 回答 2

1

poll/epoll/select用于写作相当棘手。原因是套接字大多准备好写入,除非它们的套接字发送缓冲区已满。因此,“可写”的轮询很容易在没有等待的情况下旋转。

您需要执行以下操作:

  1. 当你有东西要写入一个套接字时,在一个循环中写入它,当所有数据都被写入 write()返回 -1时终止errno == EAGAIN/EWOULDBLOCK

  2. 那时你有一个完整的套接字发送缓冲区。因此,您需要使用 selector/poll/epoll 注册此套接字以实现可写性。

  3. 当您无事可做时,选择/轮询/epoll 并重复导致相关套接字被轮询可写性的写入。

  4. 以与 (1) 相同的方式进行这些写入,但是这一次,如果写入完成,请取消注册套接字的可写性。

换句话说,如果您已经知道套接字的发送缓冲区已满,则您必须仅选择/轮询可写性,并且您必须立即停止这样做,您知道它不是。

如何将所有这些融入您的应用程序是另一个问题。

于 2013-06-14T02:30:58.210 回答
1

我会适应生产者/消费者模式。在这种情况下,一个生产者和几个消费者。

让主线程处理您的源(作为生产者)并为每个连接生成一个线程(作为消费者)。

并行的踏板每个都拉出一大块源并通过连接一个接一个地发送它。

在此设置中,保持最快连接的线程预计将发送最多的块。

于 2013-06-13T11:41:06.387 回答