【问题标题】:Two programs blocking each other while communicating in local loop两个程序在本地循环中通信时相互阻塞
【发布时间】:2014-10-18 11:43:24
【问题描述】:

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

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

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

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

代码sn-ps:

// 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。键入“再见”以关闭。 6

【问题讨论】:

  • 示例代码将有助于回答您的问题。没有它,很难给出有意义的答案。另外 - 用语言标记很有用。
  • 为什么这被标记为Java?
  • 您确定线程设置正确吗?你的监听函数有一个无限循环。您的客户端不太可能阻止来自服务器进程的资源。客户端对服务器需要的任何东西(CPU、内存、网络、服务器端口)没有独占访问权。
  • 我以pthread_create(&amp;listener, NULL, &amp;Client::listenLaunch, this); 开始线程,其中listenLaunch 是一个调用this-&gt;listen() 的包装函数。
  • @mattm IIUC 服务器和客户端在同一台机器上,所以客户端确实可以访问所有资源;-)。 (这是否是我不敢说的问题。)

标签: c++ multithreading


【解决方案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>

【讨论】:

  • 消息后面的换行符似乎解决了问题。但是我不认为回显服务器请求了这个,因为它确实打印了它已收到消息。我认为客户端缓冲了这个或者服务器缓冲了它在OutputStream中。
猜你喜欢
  • 2017-11-15
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 2022-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多