在 Unix 系统上,路径名通常几乎没有长度限制(Linux 上为 4096 个字符)...除了套接字文件路径限制为大约 100 个字符(Linux上为 107 个字符)。
我已经检查过是否可以通过更改当前工作目录并在各个目录中创建多个使用相同路径的套接字文件来解决此限制./myfile.sock:客户端应用程序似乎正确连接到预期的服务器进程,即使lsof显示所有他们在同一个套接字文件路径上侦听。
所以我已经阅读了很多关于 unix-stream 辅助数据的信息,但是所有文档中缺少的一件事是当部分读取时应该发生什么?
假设我将以下消息接收到一个 24 字节的缓冲区中
msg1 [20 byes] (no ancillary data)
msg2 [7 bytes] (2 file descriptors)
msg3 [7 bytes] (1 file descriptor)
msg4 [10 bytes] (no ancillary data)
msg5 [7 bytes] (5 file descriptors)
Run Code Online (Sandbox Code Playgroud)
第一次调用 recvmsg,我得到了 msg1 的全部(和 msg2 的一部分?操作系统会这样做吗?)如果我得到了 msg2 的一部分,我是否立即得到了辅助数据,并需要保存它以备下次读取当我知道消息实际上告诉我如何处理数据时?如果我从 msg1 中释放 20 个字节,然后再次调用 recvmsg,它会同时传送 msg3 和 msg4 吗?来自 msg3 和 msg4 的辅助数据是否连接在控制消息结构中?
虽然我可以编写测试程序来通过实验找出这一点,但我正在寻找有关辅助数据在流上下文中如何表现的文档。我在上面找不到任何官方信息,这似乎很奇怪。
我将在这里添加我的实验结果,这是我从这个测试程序中得到的:
https://github.com/nrdvana/daemonproxy/blob/master/src/ancillary_test.c
只要在调用 recvmsg 期间不需要传递先前的辅助有效载荷,Linux 就会将部分辅助承载消息附加到其他消息的末尾。一旦一个消息的辅助数据被传送,它将返回一个简短的读取而不是开始下一个辅助数据消息。所以,在上面的例子中,我得到的读数是:
recv1: [24 bytes] (msg1 + partial msg2 with msg2's 2 file descriptors) …Run Code Online (Sandbox Code Playgroud) 可以使用tcpdump/进行 TCP/IP 和 UDP 捕获,dumpcap并生成一个 pcap/pcapng 文件,该文件可以提供给 Wireshark 进行进一步分析。是否存在用于命名 Unix 域套接字的类似工具?(不过,适用于抽象套接字的通用解决方案也很好。)
strace按原样是不够的,过滤 Unix 域套接字 I/O 并不简单。使用socat或类似的代理也不适合,因为目标是对现有开放程序的被动分析。
如何获取可在 Wireshark 中用于分析的数据包捕获?示例协议应用程序是 X11(Xorg,我当前的应用程序)和 cURL/PHP (HTTP)。我CONFIG_UNIX_DIAG在 Linux 内核中看到了一个选项,这个有什么用吗?
StackOverflow 上有一个关于为守护进程提供更好的锁(由Eduardo Fleury合成)的很好的答案,该锁不依赖于守护进程的通用 PID 文件锁定机制。关于为什么 PID 锁定文件有时会导致问题,那里有很多很好的评论,所以我不会在这里重新讨论它们。
简而言之,该解决方案依赖于 Linux 抽象命名空间域套接字,它通过名称为您跟踪套接字,而不是依赖于文件,文件在守护进程被 SIGKILL 后仍然存在。该示例显示 Linux 似乎在进程死后释放套接字。
但是我在 Linux 中找不到明确的文档来说明当绑定进程被 SIGKILL 时 Linux 对抽象套接字做了什么。有人知道吗?
换句话说,抽象套接字何时被释放以供再次使用?
我不想用抽象套接字替换 PID 文件机制,除非它最终解决了问题。
根据我的经验,如果没有设置 x 位,非特权用户无法访问他/她不拥有的 unix 套接字。这个位到底有什么作用?谢谢
在我的 Android 设备上,有一个名为/proc/net/unixwho's content的文件 不符合任何标准linux 发行版的文件(显示 unix 域套接字。)前几行:
Num RefCount Protocol Flags Type St Inode Path
00000000: 00000002 00000000 00000000 0002 01 5287581 /data/misc/wifi/sockets/wpa_ctrl_789-3189
00000000: 00000003 00000000 00000000 0001 03 6402 /dev/socket/qmux_radio/qmux_client_socket 297
00000000: 00000002 00000000 00010000 0001 01 7180 /dev/.secure_storage/ssd_socket
00000000: 00000002 00000000 00010000 0001 01 6424 /dev/socket/cnd
00000000: 00000002 00000000 00010000 0001 01 6400 @QMulticlient
...
Run Code Online (Sandbox Code Playgroud)
(1) 这些不同的列代表什么?
编辑:好的,我发现了这个:
这里'Num'是内核表槽号,'RefCount'是套接字的用户数,'Protocol'当前始终为0,'Flags'代表保持套接字状态的内部内核标志。当前,类型始终为“1”(内核尚不支持 Unix 域数据报套接字)。'St' 是套接字的内部状态,Path 是套接字的绑定路径(如果有)。
但是,这不是最新的,因为我们有一个type并且没有澄清“内部状态”的含义。
(2) 同样在路径的末尾,有时会有一个没有自己列名的附加数字。那是什么?
此外,我可以在内核源代码中的哪个位置找到它的创建位置? …
两个或多个进程并发读/写是否可以unix socket?
我做了一些测试。
这是 my sock_test.sh,它产生 50 个客户端,每个客户端同时写入 5K 消息:
#! /bin/bash --
SOC='/tmp/tst.socket'
test_fn() {
soc=$1
txt=$2
for x in {1..5000}; do
echo "${txt}" | socat - UNIX-CONNECT:"${soc}"
done
}
for x in {01..50}; do
test_fn "${SOC}" "Test_${x}" &
done
Run Code Online (Sandbox Code Playgroud)
然后我创建一个unix socket并将所有流量捕获到文件sock_test.txt:
# netcat -klU /tmp/tst.socket | tee ./sock_test.txt
Run Code Online (Sandbox Code Playgroud)
最后,我运行我的测试脚本 ( sock_test.sh) 并在屏幕上监控所有 50 名工人的工作。最后,我检查所有消息是否都已到达目的地:
# ./sock_test.sh
# sort ./sock_test.txt | uniq -c
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,没有错误,所有 50 名工作人员都成功发送了所有 5K 消息。
我想我必须得出结论,同时写入unix sockets …
据我了解,AF_NETLINK 套接字协议用于内核和用户空间之间的通信,AF_UNIX 用于两个用户空间进程之间的通信。
为什么 Linux 需要单独的 AF_NETLINK?为什么 UNIX 套接字不能用于内核和用户之间的通信?
一段时间后,我在启动应用程序时遇到问题,例如 Viber。
$ /opt/viber/Viber
QSqlDatabasePrivate::removeDatabase: connection 'ConfigureDBConnection' is still in use, all queries will cease to work.
Maximum number of clients reached
(Viber:1279): Gtk-WARNING **: cannot open display: :0
Run Code Online (Sandbox Code Playgroud)
Skype
$ skype
Maximum number of clients reached
Run Code Online (Sandbox Code Playgroud)
Gnote
$ gnote
Maximum number of clients reached
** (gnote:21284): WARNING **: Could not open X display
Maximum number of clients reached
(gnote:21284): Gtk-WARNING **: cannot open display: :0
Run Code Online (Sandbox Code Playgroud)
停止
$ xrestop
Maximum number of clients reachedxrestop: Unable to open display!
Run Code Online (Sandbox Code Playgroud)
经过一番研究,我发现它与unix套接字的某些限制有关。
$ …Run Code Online (Sandbox Code Playgroud) Linux 记录了 tcp 的默认缓冲区大小,但没有记录 AF_UNIX(“本地”)套接字的默认缓冲区大小。可以在运行时读取(或写入)该值。
cat /proc/sys/net/core/[rw]mem_default
Run Code Online (Sandbox Code Playgroud)
这个值是否总是在不同的 Linux 内核中设置相同,或者是否有一系列可能的值?
unix-sockets ×10
linux ×5
socket ×2
android ×1
debugging ×1
filenames ×1
filesystems ×1
limit ×1
linux-kernel ×1
linux-mint ×1
pcap ×1
permissions ×1
proc ×1
x11 ×1
xorg ×1