TCP C在不接收数据时发送数据

时间:2019-05-21 16:33:03

标签: c++ tcp

即使客户端未先向我发送消息,我仍在尝试向连接的客户端发送数据。

这是我当前的代码:

while (true) {
    // open a new socket to transmit data per connection
    int sock;
    if ((sock = accept(listen_sock, (sockaddr *) &client_address, &client_address_len)) < 0) {
        logger.log(TYPE::ERROR, "server::could not open a socket to accept data");
        exit(0);
    }

    int n = 0, total_received_bytes = 0, max_len = 4096;
    std::vector<char> buffer(max_len);

    logger.log(TYPE::SUCCESS,
               "server::client connected with ip address: " + std::string(inet_ntoa(client_address.sin_addr)));

    // keep running as long as the client keeps the connection open
    while (true) {
        n = recv(sock, &buffer[0], buffer.size(), 0);
        if (n > 0) {
            total_received_bytes += n;

            std::string str(buffer.begin(), buffer.end());

            KV key_value = kv_from(vector_from(str));

            messaging.set_command(key_value);
        }

        std::string message = "hmc::" + messaging.get_value("hmc") + "---" + "sonar::" + messaging.get_value("sonar") + "\n";
        send(sock, message.c_str(), message.length(), 0);
    }

    logger.log(TYPE::INFO, "server::connection closed");
    close(sock);
}

我认为通过将n = recv(sock, &buffer[0], buffer.size(), 0);移到while条件之外,它将无限期地发送数据,但这不是事实。

谢谢。

解决方案

MSG_DONTWAIT函数中添加recv启用了我正在寻找的非阻塞操作。

1 个答案:

答案 0 :(得分:1)

首先,我将解释为什么它不起作用,然后我将提出解决方案的建议。基本上,您可以在man7.org> Linux>手册页中找到答案,对于特定的here也可以找到答案。

当调用函数“ recv”时,它将不返回,直到数据可用并且可以读取为止。功能的这种行为称为“阻塞”。意思是,当前执行线程被阻塞,直到读取数据为止。

所以,调用函数

n = recv(sock, &buffer[0], buffer.size(), 0);

像您一样,会造成麻烦。您还需要检查返回码。 0表示连接已关闭,-1表示错误,您必须检查errno以获取更多信息。

您可以在套接字的整个生命周期中使用函数fnctl和O_NONBLOCK标志将套接字修改为以非阻塞模式工作。您还可以将标志MSG_DONTWAIT用作第4个参数(标志),以按功能调用为基础解除对功能的阻塞。

在两种情况下,如果没有可用数据,函数将返回-1,并且您需要检查errno的EAGAIN或EWOULDBLOCK。

返回值0表示连接已关闭。

但是从体系结构的角度来看,我不建议使用这种方法。您可以使用多个线程来接收和发送数据,或者使用Linux,可以使用select,poll或类似功能之一。甚至有一个通用的设计模式。它称为“反应器”,也有可用的相关模式,例如“接收器/连接器”和“反应器” /“ ACT”。如果您打算编写一个更强大的应用程序,则可以考虑使用。

您将找到Acceptor,Connector,Reactor,Proactor,ACT here

的实现。

希望这会有所帮助