简介
上一篇文章咱们解说了 Socket 的分类和最罕用到的 Stream Socket,Stream Socket 个别是基于 TCP 协定的,所以咱们常常在 web 服务中可能看到他们的身影。当然 TCP 协定有个孪生兄弟叫做 UDP,那么基于 UDP 来做传输协定的 socket 协定就叫做 Datagram Socket,明天咱们一起来具体理解一下 Datagram Socket。
什么是 Datagram Socket
和有连贯的 Stream Socket 不同,Datagram Socket 是无连贯的。有连贯的 Stream Socket 表明这个 socket 是稳固牢靠的,所以咱们能够在 Stream socket 中进行稳固的数据传输,当然这个稳固是说数据包不会失落,然而并不一定可能确保数据包不被篡改。
Datagram Socket 这种无连贯的通常被用在答应数据局部失落的场景,比方语音、视频等等,无连贯的益处就是不须要 TCP 那样简单的建设连贯的步骤,所以相对而言更加简略。
Datagram Socket 通常应用的就是 UDP 协定作为底层的数据传输协定。
对于 UDP 来说,因为 UDP 协定自身并不会保证数据的程序和数据异样的解决,这些都须要在应用程序中本人实现。
常见的 UDP 利用有 DNS(Domain Name System) 服务,NTP(Network Time Protocol) 服务等等。
在 JDK 的 java.net 包中提供了对 Datagram Socket 的封装, 在其中定义了三个连贯的状态:
class DatagramSocket implements java.io.Closeable {
...
static final int ST_NOT_CONNECTED = 0;
static final int ST_CONNECTED = 1;
static final int ST_CONNECTED_NO_IMPL = 2;
...
}
别离示意没有建设连贯,建设了连贯和建设了连贯,然而还没有到实现的 level。
另外,在 DatagramSocket 中还蕴含了一个连贯的地址和端口:
InetAddress connectedAddress = null;
int connectedPort = -1;
应用 socat 来创立 UDP 服务
留神,在应用后续的命令之前,须要在 unix 环境中执行装置命令:yum install iproute2 netcat-openbsd socat
和之前的 Stream Socket 一样,咱们也能够应用 socat 命令,来建设一个 UDP 服务器,咱们须要用到 socat 的上面几个参数:
udp4-listen:<port> groups=FD,SOCKET,LISTEN,CHILD,RANGE,IP4,UDP
udp6-listen:<port> groups=FD,SOCKET,LISTEN,CHILD,RANGE,IP6,UDP
咱们须要监听 udp4 和 udp6 的数据,所以这里应用 udp4-listen 和 udp6-listen 两个参数。
前面的端口号能够自定义,这里咱们还是应用同样的 8888 端口,对应的命令如下:
socat UDP4-LISTEN:8888,fork /dev/null&
socat UDP6-LISTEN:8888,ipv6only=1,fork /dev/null&
下面的命令,咱们在 8888 端口上监听 UDP4 和 UDP6 的连贯信息,其中 fork 参数示意程序在接管到程序包之后持续运行,如果不必 fork,那么程序会主动退出。
socat 前面原本要接一个 bi-address,这里咱们应用 /dev/null,示意抛弃掉所有的 income 信息。
UDP6-LISTEN 有个非凡的参数叫做 ipv6only,示意收到的数据包不要发送到 IPv4-mapped IPv6 addresses。
什么是 IPv4-mapped IPv6 addresses?简略点说就是将 IPv4 映射到了 IPv6 的地址中。
执行上述命令,咱们会失去上面的输入:
[1] 16174
[2] 16184
因为是后盾执行,所以咱们返回了过程的 ID。
应用 ss 命令来监控 Datagram Sockets
ss 命令能够用来查看 socket 的状态,这里咱们须要用到 ss 的这样几个参数:
-4, --ipv4 display only IP version 4 sockets
-u, --udp display only UDP sockets
-l, --listening display listening sockets
-n, --numeric don't resolve service names
因为咱们只监听 ipv4 和 ipv6 的数据,所以这里咱们用 - 4 和 - 6 这两个参数。
另外因为只须要监听 udp sockets,所以须要应用 - u 参数。
因为是监听,所以应用 - l 参数,最初咱们心愿看到具体的数字,而不是被解析成了服务名,所以这里应用 - n 参数。
咱们应用上面的命令看看后果:
ss -4 -uln
能够失去上面的后果:
State Recv-Q Send-Q Local Address:Port Peer Address:Port
UNCONN 0 0 *:8888 *:*
下面的命令只监听了 Ipv4,咱们再看看 Ipv6:
ss -6 -uln
能够失去上面的后果:
State Recv-Q Send-Q Local Address:Port Peer Address:Port
UNCONN 0 0 :::8888 :::*
和 Ipv4 的很相似,示意咱们在 Ipv6 上监听到了端口 8888。
应用 nc 建设和 UDP Socket 的连贯
咱们曾经建设好了了监听 UDP 连贯的服务器,接下来咱们尝试应用 nc 命令来进行连贯。
nc 是 Ncat 的简称,是一个十分小并且高效的网络工具。咱们来看下本例子中会用到的参数:
-4 Use IPv4 only
-6 Use IPv6 only
-u, --udp Use UDP instead of default TCP
-v, --verbose Set verbosity level (can be used several times)
-z Zero-I/O mode, report connection status only
因为须要连贯到 Ipv4 和 Ipv6,所以须要 - 4 和 - 6 参数。
默认状况下 nc 应用的是 TCP 协定,如果要应用 udp 则须要应用 - u 这个参数。
另外咱们须要输入具体的信息,所以须要 - v 参数,最初咱们间接建设连贯,并不发送任何数据,所以这里应用 - z 参数,咱们执行一下来看看成果:
nc -4 -u -vz 127.0.0.1 8888
看看上面的输入后果:
Ncat: Version 7.50 (https://nmap.org/ncat)
Ncat: Connected to 127.0.0.1:8888.
Ncat: UDP packet sent successfully
Ncat: 1 bytes sent, 0 bytes received in 2.02 seconds.
示意 UDP 连贯胜利。
同样的,咱们能够应用上面的命令来连贯到 UDP socket:
nc -6 -u -vz ::1 8888
其中::1 示意的是本机的 ipv6 地址.
能够失去上面的后果:
Ncat: Version 7.50 (https://nmap.org/ncat)
Ncat: Connected to ::1:8888.
Ncat: UDP packet sent successfully
Ncat: 1 bytes sent, 0 bytes received in 2.02 seconds.
示意 UDP 连贯胜利。
总结
本文解说了 datagram socket 的基本概念,并且应用一些 unix 的根本命令来构建了 udp 服务器和客户端,不便大家了解。
本文已收录于 http://www.flydean.com/16-datagram-socket/
最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!
欢送关注我的公众号:「程序那些事」, 懂技术,更懂你!