c++ - 管理多个 UDP 套接字的超时

标签 c++ sockets timeout udp

我必须在 Windows 和 Linux 上为大学类(class)编写 TFTP(普通文件传输协议(protocol))服务器。我正在使用 C++,我想使用一个线程和 select() 来检查新的传入数据包。 TFTP 要求如果某个数据包在一定时间内未得到确认,则重新发送该数据包。我想知道管理这些多次超时的最佳方法是什么。

我正在考虑创建一个 std::list,其中包含将连接与发生超时的绝对时间相关联的对象。该列表按增加的超时时间排序(所有超时在分配时都是相同的,因此新超时始终是最大的并且可以到达列表的末尾 - 否则我需要一个 map 而不是列表)。< br/> 由于我需要重置连接超时,如果数据包及时到达,我想创建一个 std::map 将连接与指向其在列表中的位置的迭代器相关联。当更新连接的超时时,可以快速找到列表中的元素,更新并移动到列表的末尾(再次假设新的超时是最大的)。

这是处理问题的好方法还是有更简单的方法?

最佳答案

如果我理解正确的话,你有一对连接/超时,你希望能够通过连接和超时来访问这些对。 通过连接是因为当你收到一个数据包时你必须改变超时,而通过超时是因为你需要知道下一个连接是什么超时。

如果您不反对 boost,请查看 multi_index .

如果你想自己滚动,你可以保留两组指针,给集合不同的比较函数:

class Connection {
    ...
public:
    int GetTimeout() const;
    int GetID() const;
};

class TimeIsLess {
public:
    bool operator()(const Connection*c1, const Connection*c2) const {
        return c1->GetTimeout() < c2->GetTimeout();
    }
}
class IdIsLess {
public:
    bool operator()(const Connection*c1, const Connection*c2) const {
        return c1->GetId() < c2->GetId();
    }
}

std::set<Connection*,TimeIsLess> connectionsByTime;
std::set<Connection*,IdIsLess> connectionsById;

创建连接:

...
Connection * c = new Connection(id, timeout);
connectionsByTime.insert(c);
connectionsById.insert(c);
...

要获取下一个将超时的连接,只需获取第一个:

auto nextToTimeout = connectionsByTime.begin();
if (nextToTimeout != connectionsByTime.end())
{
    if ( (*nextToTimeout)->GetTimeout() < now )
    {
        // Close the connection
    }
}

要删除连接,您必须从一组中删除指针,然后从另一组中删除和删除指针。

我没有编译它,所以不要在打字错误上钉我 (:

关于c++ - 管理多个 UDP 套接字的超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7533636/

相关文章:

sockets - 为什么 Sendto() 系统调用不返回发送的字节数?

java - Android 应用程序中套接字 DataInputStream BufferedInputStream 的消息顺序错误

multithreading - Haskell 计算密集型线程阻塞所有其他线程

c++ - 模板类型是可选的吗?

c++ - 如何组织 C++ 项目

c++ - 为什么通过指针交换在 C++ 中的 vector 中不起作用?

java - 如何增加java中的事务超时(使用weblogic)

c++ - 为什么 std::multimap 没有实现 try_emplace?

python - 在 Python asyncio 中检测套接字 EOF

http - 使用 Berkeley Sockets 接收未知大小的数据