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

Two programs blocking each other while communicating in local loop

本文关键字:通信 循环 两个 程序      更新时间:2023-10-16

我已经编程了一个简单的c++客户端,它应该通过Ubuntu 14.04上的本地循环使用侦听线程(Java中下载的EchoServer)与另一个程序通信。然而,在以下情况下存在问题:

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

在下一步中,服务器应该接收服务器发送的消息,但它没有。相反,它在客户端终止后首先接收消息。

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

代码片段:

// 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] = '';
            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。键入"再见"关闭。6

EchoServer实现通常希望在回显消息之前,在您发送的消息上看到一条换行符。尝试client.send("hellon")而不是client.send("hello")

此外,尽管这对于您正在尝试的应用程序来说并不是真正必要的,但您可能希望关闭客户端套接字上的Nagle算法,以便立即发送小消息。在使用客户端套接字调用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>