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

C++ TCP C在不接收数据时发送数据,c++,tcp,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.

我正在尝试向连接的客户端发送数据,即使客户端没有首先向我发送消息

这是我当前的代码:

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=recvsock,&buffer[0],buffer.size,0;在while条件之外,它将无限期地发送数据,但事实并非如此

提前谢谢

解决方案
将MSG_DONTWAIT添加到我正在寻找的已启用recv功能的非阻塞操作中。

首先,我将解释它不起作用的原因,然后我将提出解决方案建议。基本上,您可以在man7.org>Linux>手册页中找到答案,并特别针对recv

调用函数recv时,它将不会返回,直到数据可用且可以读取为止。函数的这种行为称为阻塞。表示当前执行线程被阻塞,直到数据被读取

因此,调用函数

n = recv(sock, &buffer[0], buffer.size(), 0);
正如你所做的那样,造成了麻烦。您还需要检查返回代码。0表示连接已关闭,-1表示错误,您必须检查errno以了解更多信息

在套接字的生命周期内,您可以使用函数fnctl和O_NONBLOCK标志修改套接字,使其在非阻塞模式下工作。您还可以将标志MSG_DONTWAIT用作第四个参数标志,以在每个函数调用基础上解除对函数的阻塞

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

返回值0表示连接已关闭

但是从架构的角度来看,我不建议使用这种方法。您可以使用多个线程来接收和发送数据,或者使用Linux,使用select、poll或类似函数之一。甚至有一个通用的设计模式。它被称为反应器,也有相关的模式,如受体/连接器和前体/动作可用。如果你计划编写一个更健壮的应用程序,那么你可以考虑那些。 您将找到接受器、连接器、反应器、前置器、ACT的实现


希望这有帮助

但事实并非如此。-实际发生了什么?如果n>0,请尝试在条件之后打印一些调试日志。你的问题还不清楚,到底发生了什么?此外,在调用recv之前尝试使用“select”函数。在recv中使用MSG_DONTWAIT标志。检查错误:recv并发送return-1返回错误。@gudok这就是我要找的for@TheoBouwman请不要编辑您的问题以提供解决方案。写一个完整的自我回答你的问题是如何解决的。谢谢你的清晰解释。这只是一个概念证明,所以实现您提到的模式将在后面介绍。