在同一 unix 套接字连接中读取元素两次时出错

Error reading an element twice in the same unix socket connection

本文关键字:两次 出错 元素 读取 unix 套接字 连接      更新时间:2023-10-16

我面临着一个相当奇怪的问题。我在 ruby 和 C 之间创建了一个 unix 套接字服务器,在 C 端,主线程创建并侦听套接字,并在接受或连接时让线程(来自线程池)执行信息的读取和处理。

看到每当我负载高时,我的 accept() 都会接受 2 或 3 次相同的连接。这通常伴随着客户端在实际上应该发送的连接上向我抛出"管道破裂"消息。

例如:

客户:

Sending 1
Sending 2
Sending 3
Error is Broken pipe
Sending 4
Sending 5
...

服务器:

New connection is 1
New connection is 2
New connection is 2 <<<< this should not be here!
New connection is 4
New connection is 5
New connection is 6

我的代码是(C++代码,服务器)

//(... create the socket with standard socket, bind and listen calls)
while(1) {
        // Wait for connection
        int connection = accept(streamSocket, (struct sockaddr *) &clientAddress, &clilen);
        if (connection < 0){
            LOG(ERROR) << "Failed to accept new client socket connection, request index = " << requests;
            break;
        }
        else
            printf("New connection is %dn", connection);
        // Add connection to handler thread in pool
        pool.AddJob([this, connection, requests, streamSocket]() {
            char buffer[BUFFER_SIZE];
            bzero(buffer, BUFFER_SIZE);
            int n = read(connection, buffer, BUFFER_SIZE-1);
            //(... processing of the info)
        }
        close(connection);
        });
    }

而 ruby 中的客户端(在循环中运行):

request = "whatever json"
for count in 1..10
  begin
    puts "Sending #{count}"
    socket = UNIXSocket.new("/tmp/mysocket.socket")
    socket.puts(request)
    response = socket.read
    socket.close
  rescue Exception => e
    puts "Error is #{e}"
  end
end

更新

我已经看到使用 socket.send 或 socket.write 而不是 socket.put 我没有收到任何"断管"错误,因此在 C 端没有重复接受。尽管如此,我已经在线检查过,它们之间唯一的(父级)区别似乎是socket.puts在消息末尾添加了换行符。我想知道为什么看跌不起作用以及推荐哪一个(发送或写入)。

New connection is 2
<--- You probably have closed connection 2 here. Double check your code
New connection is 2 <<<< this should not be here!

当客户端写入服务器已关闭的连接时,它将触发Broken pipe信号。