繁体   English   中英

异步 C++ 套接字

[英]Async C++ socket

我正在尝试编写一个异步服务器来同时处理多个用户。 服务器站在主线程中监听接收数据,在同一个线程中它接收它们(大图像)并创建一个任务来处理这个数据,它发送到线程池,并且它自己监听下一个图像。 这是代码(句柄包含在另一个线程上执行的数据处理):

while (true) {
    cv::Mat data = ReceiveImage();

    m_Pool.AddTask([=]() mutable {
        Handle(std::move(data));
    });
}

cv::Mat UDPServer::ReceiveImage() const {
    ...
    try {
        for (int i = 0; i < sz; i += num_bytes) {
            num_bytes = ReceiveData((char*)&buf[0] + i, sz - i, from);
        }
    }
    ...
}

int UDPServer::ReceiveData(char* buf, int len, sockaddr_in& from) const {
    socklen_t slen = sizeof(from);
    int nReceivedBytes = recvfrom(m_Socket, buf, len, 0, (sockaddr*)&from, &slen);

    if (nReceivedBytes == SOCKET_ERROR) {
        throw std::runtime_error(RECEIVEFROM_ERROR.data());
    }

    return nReceivedBytes;
}

这种方法有一个问题:在接受来自一个用户的数据时,另一个用户可以发送他的数据,但不会被接受。

一个可能的解决方案是接受不同线程上的数据。 为此,我只想在主线程中接收数据已到达的信号,并将它们传输到另一个线程以接收并将它们发送到线程池。 类似于 MPI 中的 Probe。

这如何在 C++ 套接字上实现? 我试图在互联网上找到它,但没有任何结果。 或者有人有更好的解决方案吗?

TCP 套接字以这种方式工作。 有一种收听的插座,称之为P,和实际的通信插座,称之为问: accept系统调用做到这一点:

Q = accept(P, ...); // there are other parameters 
                    // which are not important here

一旦accept返回,您就可以在Q上启动一个异步任务,并继续在P上监听。这两个作业不会相互干扰。 如果另一个请求来了,为什么你还在磨 Q, accept只会为另一个异步任务返回另一个 Q。

整个想法对于 UDP 并不适用,因为没有持久连接。 每个数据包都是它自己的一个通信会话。 从套接字异步读取数据包没有多大意义。 读取是原子操作,数据包足够短。 您可以启动一个异步任务来处理每个数据包的数据,这没有任何问题。 您可以尝试通过poll套接字并启动异步任务来实现异步读取,该任务在数据准备就绪后立即读取数据,但这不会真正简化或加速任何事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM