UNIX域套接字C++服务器无法将数据返回到客户端

UNIX domain socket C++ server can not return data to client

本文关键字:数据 返回 客户端 套接字 C++ 服务器 UNIX      更新时间:2023-10-16

这是我正在使用的简单echo服务器,服务器将接受客户端的请求并返回客户端发送给它的内容。该程序与socat配合使用很好,但在使用自己的客户端时会冻结。

我的旧代码存在的问题是我使用read而不是read_someread将阻塞管道,直到它读取特定数量的字节或获得断开的管道异常,而read_some将一次读取一个块。更新后的版本使用read_some读取输入流,并检查程序读取的最后一个字符是否是,如果是,则意味着它到达了命令的末尾,因此它将回显。这是因为我只传递字符串文字,而管道中没有二进制数据。

服务器的代码是

using namespace std;
const char* epStr = "/tmp/socketDemo";
int main() {
  namespace local = boost::asio::local;
  boost::asio::io_service io_service;
  ::unlink(epStr);
  local::stream_protocol::endpoint ep(epStr);
  local::stream_protocol::acceptor acceptor(io_service, ep);
  while(1) {
    local::stream_protocol::socket *socket = new local::stream_protocol::socket(io_service);
    acceptor.accept(*socket);
    char buf[2048] = {0};
    boost::system::error_code error;
    size_t len = 0;
      while(1) {
        len += socket->read_some(boost::asio::buffer(buf + len, 2048 - len));
        cout << "read " << len << endl;
        if (buf[len] == '') {
          break;
        }
      }
    cout << "read " << len << " bytes" << endl;
    cout << buf << endl;
    boost::asio::write(*socket, boost::asio::buffer(buf, len), boost::asio::transfer_all());
  }
}

使用socat命令测试服务器时,例如

echo "12345" | socat - UNIX-CONNECT:/tmp/socketDemo

它将返回期望的结果。

我的客户代码是

const char* epStr = "/tmp/socketDemo";
int main(int argc, const char* argv[]) {
  boost::asio::io_service io_service;
  boost::asio::local::stream_protocol::endpoint ep(epStr);
  boost::asio::local::stream_protocol::socket socket(io_service);
  socket.connect(ep);
  boost::asio::write(socket, boost::asio::buffer(argv[1], strlen(argv[1])), boost::asio::transfer_all());
  char buf[1024] = {0};
  size_t len = 0;
    while(1) {
      len += socket.read_some(boost::asio::buffer(buf + len, 2048 - len));
      std::cout << "read " << len << std::endl;
      if (buf[len] == '') {
        break;
      }
    }
  std::cout << "read " << len << " bytesn";
  std::cout << buf << std::endl;
  socket.close();

当执行客户端时,起初两者都没有输出,在我杀死客户端后,服务器会输出它读取了n个字节,并得到一个坏管道异常。

这可能是由服务器中的read功能引起的吗?如果是这样的话,有没有一种方法可以让它知道应该读取多少数据,而不必在每条消息的开头发送数据块的大小?我还想知道为什么socat可以与此服务器一起工作而没有任何问题?谢谢

我还想知道为什么socat可以在没有任何服务器的情况下使用此服务器问题

可能是因为socat关闭了套接字,而您的客户端没有。

如果是的话,有没有办法让它知道应该读取多少数据而不在每个开始时发送数据块的大小消息

例如,假设您正在定义/使用包含EOM的协议,一次读取一个字节,直到您读取到消息末尾字符。