Featured image of post tcp loopbcak与unix domain区别与性能对比,在Linux系统中如何使用这两种网络通信方式,展示Unix套接字的使用方法

tcp loopbcak与unix domain区别

了解 TCP 本地回环和 Unix 域套接字的区别与性能对比,探讨在 Linux 系统中如何使用这两种网络通信方式,并通过代码实例展示 Unix 域套接字的使用方法。

访问本机网络的方式

访问同一台电脑上的网络,一般用的地址是 localhost 或者 127.0.0.1这两种方式,比如本机有一个Nginx服务器,想要访问本机Nginx,在浏览器中输入localhost 或者 127.0.0.1就能访问到Nginx的首页。如果要连接到本机的mysql, 在连接的时候,把地址填127.0.0.1就好了

tcp 本地回环

为什么使用localhost或者1270.0.1就能访问本机的网络或者程序呢,是因为在每台电脑上都有一个特殊的网络,这个网络就是本地回环(local loopback)。localhost可以看做是 127.0.0.1 的域名。一般在hosts文件中都会有一条配置,使 localhost 映射到1270.0.0.1

在linux系统(debin 11)中, 使用 ip a命令可以查看本机的网络

可以看到,第一个网络就是本地回环(loopback),他的 ip 地址就是就是 127.0.0.1

本地回环也是网络,是一个特殊的虚拟网卡。使用本地回环网络时,数据也会经过网络栈的封包和解包。

可以看到,tcp属于运输层(传输层)协议,所以在本机发送数据时,也会经过

1传输层->网络层->lookback->网络层->传输层

这样一个过程。

unix domain

上面说了什么是 tcp 本地回环,那什么是 unix domain 呢。unix domain 严格来说不是网络,是unix 和 linux系统提供的一个进程间通信的方式,有点类似管道。看名字也知道,unix domain 只支持unix类的系统中,windows系统是不支持的。unix 的使用方式和 tcp很像,但是底层的工作原理差别却很大。

unix domain 中的数据传输 就不需要网络栈了,可以看做是操作系统做了一次内存中的一个数据复制。

使用 unix domain

如何使用tcp 相信都很熟了,就不上demo了。只上 unix domain 的代码吧。因为 unix domain 不支持 windows系统,所以要在linux或者unix系统中测试,下面会使用go在debin中测试一下

unix domain 和tcp 一样 也是分 服务器 和 客户端 的

unix domain 服务器

 1package main
 2
 3import (
 4	"fmt"
 5	"io"
 6	"net"
 7)
 8
 9func main() {
10	listen, err := GetUnixListen("/tmp/test_server.sock")
11	if err != nil {
12		panic(err)
13	}
14
15	defer listen.Close()
16	for {
17		conn, err := listen.Accept()
18		if err != nil {
19			panic(err)
20		}
21
22		buf := make([]byte, 1024)
23		//读数据
24		n, err := conn.Read(buf)
25		if err != nil && err != io.EOF {
26			panic(err)
27		}
28		fmt.Printf("%s\n", buf[:n])
29
30		//写数据
31		_, err = conn.Write([]byte("hello"))
32		panic(err)
33	}
34}
35
36func GetUnixListen(addr string) (net.Listener, error) {
37	listen, err := net.Listen("unix", addr)
38	if err != nil {
39		return nil, err
40	}
41	return listen, nil
42}

unix domain 客户端

 1package main
 2
 3import (
 4	"fmt"
 5	"io"
 6	"net"
 7)
 8
 9func main() {
10	conn, err := GetUnixConn("/tmp/test_server.sock")
11	if err != nil {
12		panic(err)
13	}
14
15	buff := make([]byte, 1024)
16	n, err := conn.Read(buff)
17	if err != nil {
18		if err != io.EOF {
19			panic(err)
20		}
21	}
22	fmt.Printf("%s\n", buff[:n])
23
24	conn.Write([]byte("ok"))
25}
26
27func GetUnixConn(addr string) (net.Conn, error) {
28	conn, err := net.Dial("unix", addr)
29	if err != nil {
30		return nil, err
31	}
32	return conn, nil
33}

可以看到,在go中使用 unix domain的api 和tcp基本没有区别。有区别的地方是在监听和连接的地方。

tcp 通过 IP+端口的方式来确定地址的,而unix domain 同时一个文件符 来确定地址。

当unix domain开启监听后,会在目录中创建一个文件。在上面的例子中,就会在 /tmp 目录中创建一个test_server.sock 文件。 这是一个特殊的文件通过 file命令可以看到

1file test_server.sock 
2test_server.sock: socket

如果在同一个目录下有一个同名的文件,unix domain 的监听就会失败。就像一个端口默认只能被监听一次一样。

unix domain 和 tcp loopback 性能对比

我没有过严格的性能测试,只是写了一些简单的测试看了一下,在发送小的数据包时,unix domain 的性能会好于 tcp。当发送大的数据包时,两者的性能差距可以忽略不计了。

这个也是符合预期的,小的数据包时,tcp会经过网络协议栈,当数据量变大时,网络协议栈的影响可以忽略不计了。

总结

  1. tcp look back

可以在多个平台使用,通过本机的虚拟网卡完成数据传输,需要经过网络协议栈,性能开销相对大一些。

  1. unix domain

只能在unix类系统中使用,是操作系统提供的一种进程间通信方式。不需要经过网络协议栈,性能相对高一些。

发表了70篇文章 · 总计178.69k字
本博客已稳定运行
© QX
使用 Hugo 构建
主题 Stack 由 Jimmy 设计