Unix Domain Socket TCP Socket 的区别
·
using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
class server
{
static void Main()
{
string path = @"C:\temp\test.sock";
Socket serverSocket = null;
try
{
if (File.Exists(path))
File.Delete(path);
var endpoint = new UnixDomainSocketEndPoint(path);
serverSocket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
serverSocket.Bind(endpoint);
serverSocket.Listen(5);
Console.WriteLine("Unix socket ready: " + path);
Console.WriteLine("Press Ctrl+C to stop.");
while (true)
{
try
{
Socket client = serverSocket.Accept();
byte[] buffer = new byte[1024];
int len = client.Receive(buffer);
string msg = Encoding.UTF8.GetString(buffer, 0, len);
Console.WriteLine("Received: " + msg);
client.Send(Encoding.UTF8.GetBytes("hello"));
client.Close();
}
catch (SocketException ex)
{
Console.WriteLine("Client socket error: " + ex.Message);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Server error:");
Console.WriteLine(ex.ToString());
}
finally
{
if (serverSocket != null)
{
try
{
serverSocket.Close();
}
catch { }
}
Console.WriteLine();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
}
using System;
using System.Net.Sockets;
using System.Text;
class Client
{
static void Main()
{
var endpoint = new UnixDomainSocketEndPoint(@"C:\temp\test.sock");
Socket client = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
client.Connect(endpoint);
client.Send(Encoding.UTF8.GetBytes("ping"));
byte[] buffer = new byte[1024];
int len = client.Receive(buffer);
Console.WriteLine("Server: " + Encoding.UTF8.GetString(buffer, 0, len));
client.Close();
}
}
这段代码使用的是 Unix Domain Socket(UDS),而传统的 127.0.0.1:xxxx 属于 TCP/IP Socket(AF_INET)。两者都是进程间通信(IPC)机制,但工作层次和行为差异很大。下面从 架构、性能、安全、系统实现、沙箱行为几个关键角度说明。
一、两种 Socket 的核心区别
| 特性 | Unix Domain Socket | TCP Socket (127.0.0.1:port) |
|---|---|---|
| 地址形式 | 文件路径 C:\temp\test.sock |
IP + Port 127.0.0.1:5000 |
| 协议族 | AF_UNIX |
AF_INET / AF_INET6 |
| 网络协议栈 | 不经过 TCP/IP | 必须走 TCP/IP |
| 通信范围 | 仅本机 | 本机或网络 |
| 访问控制 | 文件权限 | 端口权限/防火墙 |
| 性能 | 更高(少一层协议) | 略低 |
| 安全性 | 更高(无端口) | 需要端口 |
| 可被扫描 | 不能 | 可以 |
二、数据路径差异(最重要)
1 Unix Domain Socket
数据路径:
进程A
↓
AF_UNIX
↓
Kernel IPC
↓
进程B
特点:
-
完全不走网络栈
-
内核直接复制内存
-
延迟更低
2 TCP Socket (127.0.0.1)
数据路径:
进程A
↓
TCP/IP stack
↓
loopback interface
↓
TCP/IP stack
↓
进程B
即使是 127.0.0.1 也会经过:
TCP
IP
Loopback driver
所以会多一层协议处理。
三、性能差异(实际)
一般 IPC benchmark:
| 类型 | 延迟 | 吞吐 |
|---|---|---|
| Unix Socket | 最低 | 最高 |
| Named Pipe | 中等 | 高 |
| TCP localhost | 较高 | 中等 |
在 Linux 中:
Unix Socket ≈ 2x TCP
Windows 上差距稍小。
四、系统实现差异
Unix Socket
创建:
socket(AF_UNIX)
bind("/tmp/test.sock")
listen()
路径是 filesystem namespace。
你代码中的:
C:\temp\test.sock
只是一个 socket endpoint 文件。
TCP Socket
创建:
socket(AF_INET)
bind(127.0.0.1:5000)
listen()
端口由 network stack 管理。
五、权限控制机制
Unix Socket
通过 文件权限控制:
Linux:
srwxrwxr-x test.sock
Windows:
NTFS ACL
TCP Socket
通过:
port
firewall
network ACL
六、典型应用
Unix Domain Socket 常见用途:
| 软件 | 用途 |
|---|---|
| Docker | container runtime |
| PostgreSQL | 本地连接 |
| MySQL | local socket |
| Nginx | fastcgi |
| Redis | IPC |
| JetBrains IDE | DirectoryLock |
例如 PyCharm 就使用:
UnixDomainSocket
来做 IDE 单实例锁。
七、在 Sandboxie 中的行为
Sandboxie 对 IPC 的处理非常关键。
1 TCP Socket
在沙箱中:
127.0.0.1:5000
通常 不会被阻止。
因为 TCP/IP 属于:
network stack
沙箱不会拦截。
2 Unix Domain Socket
Unix socket 属于:
filesystem namespace
+ kernel IPC
Sandboxie 会:
路径虚拟化
IPC隔离
可能出现:
| 现象 | 原因 |
|---|---|
| BindException | socket endpoint冲突 |
| AccessDenied | 路径虚拟化 |
| 残留.sock文件 | 内核对象未释放 |
八、Sandboxie 下 socket 文件路径
真实路径:
C:\temp\test.sock
沙箱运行时可能变成:
C:\Sandbox\<user>\<box>\drive\C\temp\test.sock
这就是为什么:
File.Delete()
有时会失败。
九、JetBrains IDE 的问题来源
PyCharm 启动时执行:
DirectoryLock.tryListen
↓
UnixDomainSockets.bind
如果 Sandboxie 拦截:
bind()
就会出现:
java.net.BindException
Address already in use
实际上并不是端口冲突,而是:
IPC namespace冲突
十、一个关键对比
| 行为 | Unix Socket | TCP |
|---|---|---|
| netstat可见 | 否 | 是 |
| 端口扫描 | 否 | 是 |
| 沙箱影响 | 较大 | 较小 |
| 文件系统参与 | 是 | 否 |
十一、你的代码行为
Server:
bind(C:\temp\test.sock)
listen
accept
Client:
connect(C:\temp\test.sock)
send
recv
通信完全在:
kernel IPC
完成。
十二、什么时候应该使用哪种
建议:
| 场景 | 推荐 |
|---|---|
| 本机服务 | Unix Socket |
| 跨主机通信 | TCP |
| 高性能IPC | Unix Socket |
| 简单调试 | TCP |
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)