两个程序在本地循环中进行通信时相互阻塞

时间:2014-10-18 11:43:25

标签: c++ multithreading

我编写了一个简单的c ++客户端,它应该通过Ubuntu 14.04上的本地循环使用侦听器线程(Java下载的EchoServer)与另一个程序进行通信。但是,在以下情况下会出现问题:

  1. 客户端连接到服务器
  2. 服务器发送问候留言
  3. 客户端收到消息并向服务器发送新消息
  4. 客户等待答复;主线程休眠,侦听器线程使用recv()
  5. 等待答案

    在下一步中,服务器应该接收服务器发送的消息,但事实并非如此。相反,它会在客户端终止后首先收到消息。

    我认为问题是客户端阻塞资源,因此不允许服务器接收消息,但我不确定。不幸的是,我无法在两台独立的机器上进行测试。

    代码段:

    // main method
    int main(void) {
        Client client("127.0.0.1", 13050);
        std::cout << client.open() << std::endl;
        client.attachListener(foo);
        usleep(1000 * 1000 * 2);
        std::cout << client.send("hello") << std::endl;
    
        usleep(1000 * 1000 * 5);
    }
    
    // send method
    int Client::send(const char* msg) {
        return write(sockfd, msg, strlen(msg));
    }
    
    // listener function
    void* Client::listen() {
        char buffer[256];
        unsigned int receive_size = 0;
        while(true) {
            receive_size =  0;
            while((receive_size = recv(sockfd, &buffer, 256, 0)) > 0) {
                buffer[receive_size] = '\0';
                msgHandler(buffer);
                bzero(&buffer, 256);
            }
            if(receive_size == 0) {
                msgHandler("Server disconnected");
            } else if(receive_size == 1) {
                msgHandler("Connection failure!");
            }
        }
        return NULL;
    }
    

    输出:     1     欢迎使用Java EchoServer。输入'bye'关闭。     6

1 个答案:

答案 0 :(得分:1)

EchoServer实现通常希望在它们回送之前看到您发送的消息的换行符。而不是client.send("hello")尝试client.send("hello\n")

此外,虽然对于您刚试验的应用程序来说这不是必需的,但您可能需要关闭客户端套接字上的Nagle algorithm以便立即发送小消息。在您使用客户端套接字调用connect之后添加这样的代码:

int flag = 1;
int res = setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof flag);
if (res < 0) // handle setsockopt failure here...

此代码需要以下头文件:

#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>