【问题标题】:Bidirectional communication using a single UNIX socket使用单个 UNIX 套接字的双向通信
【发布时间】:2015-10-15 13:56:00
【问题描述】:

我有这样的情况,在后台运行的服务通过放置在文件系统上的套接字 (SOCK_DGRAM) 使其自身可用于基于 ASCII 的命令。我能够成功向该接口发送命令,但无法接收后台服务生成的任何响应。

据我了解,我没有收到服务响应的原因是因为底层 IPC 在技术上不在两个进程之间,而是在两个地址之间。因此,有必要将我的端点绑定到一个特定的地址位置,以便服务知道要发送它的响应。但是,问题是我不想用太多额外的套接字文件污染目录空间。

也就是说,我可以通过简单地执行以下操作来完成这项工作:

struct sockaddr_un local;
int len;

s = socket(AF_UNIX, SOCK_DGRAM, 0);
local.sun_family = AF_UNIX;
strcpy(local.sun_path, "/path/to/some/dir/mySocketFile");
len = strlen(local.sun_path) + sizeof(local.sun_family);
bind(s, (struct sockaddr *)&local, len);
//Send commands to control interface of background service

一切都很好,因为通过 绑定到 mySocketFile 服务有一个地址,它将响应。

简而言之,有没有办法通过其可用的套接字接口与服务进行通信并且接收响应而不绑定本地端点,以便它创建另一个套接字-在文件系统上键入文件?即某种 nameless 套接字?

当然,如果有人在我的逻辑中发现任何误解或误解,请指出。

【问题讨论】:

  • @Dinesh,是的,该链接的最佳答案基本上表达了我认为的原因。本质上,客户端和服务器都需要端点来进行正确的通信——因此每个都必须绑定到特定的套接字接口。我在问这个问题,看看是否有一种可能的方法,客户端不生成此端点,而是使用某种在文件系统上不可见的无名套接字。

标签: sockets unix ipc


【解决方案1】:

如果客户端没有将其套接字绑定到文件系统地址,它仍然有一个由系统分配的名义地址(可能存在于文件系统中的 /tmp 某处,或者可能根本不存在于文件系统中,取决于操作系统)。服务器可以通过使用 recvfrom(2) 调用来接收来自客户端的传入数据包来获取此地址——此调用需要额外的 sockaddr * 和 socklen_t * 参数,并用客户端套接字地址填充。然后使用 sendto(2) 将回复发送回客户端。

【讨论】:

  • 我认为会是这种情况,但也许我误用了套接字实用程序。我能够成功地向服务发送命令,但是 recvfrom 会无限阻塞并且永远不会返回。我确定前向通信正在到达服务,因为我命令关闭的行为符合预期。
  • 这个隐式地址是通过调用sendto 或connect 创建的吗?
  • 如果recvfrom 被阻塞,那么您显然无法在服务器中获取命令,因为获取命令的是recvfrom。如果服务以其他方式获取命令,那么您没有使用 recvfrom。
  • 我没有控制服务器监听命令。我的意思是我能够sendto 向服务器发送我的命令(例如关闭),并且服务器的响应符合预期(即关闭)。但是,服务器应该以状态响应命令;这是我在客户处没有收到的响应。服务器实际上是我与之通信的后台服务,而不是我构建或维护的任何东西。
  • 我意识到问题出在哪里:该服务没有适当的权限写入我提供给它的地址以进行响应。如果我明确指定要生成套接字文件的位置(即使用bind),那么我可以chmod 并且我能够成功接收服务器的响应,否则我不能。因此,如果我不bind 并允许操作系统创建一个临时地址,那么权限问题仍然是一个问题。有没有办法解决这个问题?
猜你喜欢
  • 1970-01-01
  • 2012-01-26
  • 2013-12-01
  • 2018-01-20
  • 1970-01-01
  • 1970-01-01
  • 2011-10-12
  • 1970-01-01
  • 2018-04-26
相关资源
最近更新 更多