乐趣区

关于java:网络协议之socket协议详解之Socket和Stream-Socket

简介

不论是在一般的网络编程中还是在 netty 中,都常常会提到一个词叫做 socket,如同 socket 是一个神奇的货色,应用 socket 咱们能够建设客户端到服务器端的连贯,并且和进行客户端和服务器端的通信,那么 socket 到底是什么呢?它有哪些分类呢?一起来看看吧。

Socket 是什么

socket 的中文翻译是套接字,集体觉的这个翻译真的是太差劲了,套接字听起来毫无意义,所以很多人在第一次听到 socket 这个词的时候必定很迷茫。

那么什么是 socket 呢?socket 是一种不同程序间进行过程通信的办法,这些程序能够在同一个服务器上也能够在不同的服务器上。

socket 建设连贯的根底是 IP 协定,IP 协定被用来进行数据的封装和分组,而后才可能在网络上进行传输。这种依赖于 IP 协定的 socket,又叫做 network socket。

通过 network socket 能够建设客户端和服务器端的连贯,客户端和服务器端是通过 socket address 来发现对方的。

以 java 为例,咱们来看下 SocketAddress 的定义:

public abstract class SocketAddress implements java.io.Serializable {static final long serialVersionUID = 5215720748342549866L;}

能够看到 SocketAddress 只是一个抽象的定义,它能够有多种实现,它具体的实现中蕴含了传输协定,比如说是 TCP,还是 UDP,另外还须要蕴含一个 IP 地址和一个连贯的端口。

其中 IP 地址和端口定义了连贯的对象,协定定义的是连贯形式。

基于不同的协定,能够衍生出不同的类型的 sockets。比方依赖于 TCP 协定的叫做 Stream sockets, 依赖于 UDP 协定的叫做 Datagram sockets, 依赖于 local files 来进行数据传输的叫做 Unix Domain Sockets.

接下来咱们会在一个 unix 零碎中具体解说这几种协定的应用。

在解说具体的例子之前,咱们须要应用到对于网络的命令,他们是 ss,nc 和 socat。

在本文中,我应用的是 centOS 零碎,所以你能够应用上面的命令进行装置:

yum install iproute2 netcat-openbsd socat

Stream Socket

什么是 Stream Socket 呢?从字面上能够看出,这个 Socket 连贯是用来进行流传输的,如果要进行流的传输,那么首先就须要建设一个稳固的网络连接,在稳固的连贯方面,毫无疑问 TCP(Transmission Control Protocol) 是最罕用也是极其高效的一种协定。

对于 Stream Socket 来说,它是有向性的,数据 package 须要从一个地址通过网络传递到另外一个地址,同时还须要承受到对方的解决返回后果,在这个过程中通常应用的就是 TCP 协定。

TCP 协定可能保证数据的稳定性和有序性,TCP 的数据包能够保障发送到物理网络接口的数据包程序。如果网络接口接管到的数据包是无序的,那么网络适配器和操作系统将确保它们以正确的程序重新组合以供应用程序应用。

常见的基于 TCP 的 Stream Socket 就是咱们经常拜访的 http 和 https 服务了,解决 http 和 https 服务的服务器个别是 nginx 或者 apache, 那么通常会有上面的 Stream Socket 地址:

124.225.141.53:80
124.225.141.53:443

下面我用的是网易的 ip 地址,其中 80 示意的是 http,443 示意的是 https。

应用 socat 创立一个 TCP 服务器

罕用的 TCP 服务器能够抉择 apache 或者 nginx,这里为了简略起见,咱们抉择应用 socat 来创立一个 TCP 服务器。

socat 是什么呢?它是 SOcket CAT 的简称,能够用来模仿一个 TCP 的服务器。

socat 的命令很简单,这里咱们只是简略介绍一下它的利用:

socat -h
socat by Gerhard Rieger and contributors - see www.dest-unreach.org
Usage:
socat [options] <bi-address> <bi-address>

从下面的后果咱们能够看出,socat 能够承受一些地址,而后能够增加一些选项。

这里咱们应用 socat 来创立两个连贯,别离是 TCP6 和 TCP4,socat 有两个选项能够做这项工作:

      tcp-connect:<host>:<port> groups=FD,SOCKET,CHILD,RETRY,IP4,IP6,TCP
      tcp-listen:<port> groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP4,IP6,TCP
      tcp4-connect:<host>:<port>        groups=FD,SOCKET,CHILD,RETRY,IP4,TCP
      tcp4-listen:<port>        groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP4,TCP
      tcp6-connect:<host>:<port>        groups=FD,SOCKET,CHILD,RETRY,IP6,TCP
      tcp6-listen:<port>        groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP6,TCP

这里咱们只须要建设两个监听 TCP 的服务,所以咱们应用上面的命令:

socat TCP4-LISTEN:8888,fork /dev/null&
socat TCP6-LISTEN:8888,ipv6only=1,fork /dev/null&

下面的命令,咱们在 8888 端口上监听 TCP4 和 TCP6 的连贯信息,其中 fork 参数示意程序在接管到程序包之后持续运行,如果不必 fork,那么程序会主动退出。

socat 前面原本要接一个 bi-address,这里咱们应用 /dev/null,示意抛弃掉所有的 income 信息。

TCP6-LISTEN 有个非凡的参数叫做 ipv6only,示意收到的数据包不要发送到 IPv4-mapped IPv6 addresses。

什么是 IPv4-mapped IPv6 addresses?简略点说就是将 IPv4 映射到了 IPv6 的地址中。

执行上述命令,咱们会失去上面的输入:

[1] 30877
[2] 30885

因为是后盾执行,所以咱们返回了过程的 ID。

应用 ss 查看 TCP 连贯

ss 是一个十分弱小的命令,咱们能够通过应用 ss 来监测 TCP sockets 的信息,它的应用状况如下:

ss -h
Usage: ss [OPTIONS]
       ss [OPTIONS] [FILTER]

咱们次要看上面几个将要用到的参数:

   -4, --ipv4          display only IP version 4 sockets
   -6, --ipv6          display only IP version 6 sockets
   -t, --tcp           display only TCP sockets
   -l, --listening     display listening sockets
  -n, --numeric       don't resolve service names

因为咱们只监听 ipv4 和 ipv6 的数据,所以这里咱们用 - 4 和 - 6 这两个参数。

另外因为只须要监听 tcp sockets,所以须要应用 - t 参数。

因为是监听,所以应用 - l 参数,最初咱们心愿看到具体的数字,而不是被解析成了服务名,所以这里应用 - n 参数。

咱们应用上面的命令看看后果:

ss -4 -tln

后果如下:

State       Recv-Q Send-Q                      Local Address:Port                                     Peer Address:Port              

LISTEN      0      5                                       *:8888                                                *:*  

示意监听到了端口 8888,当然如果你的服务器上有其余的过程,那么可能不止这一条数据。

下面的命令只监听了 Ipv4,咱们再看看 Ipv6:

ss -6 -tln

可能失去上面的输入:

ss -6 -tln
State       Recv-Q Send-Q                      Local Address:Port                                     Peer Address:Port              

LISTEN      0      5                                      :::8888                                               :::* 

和 Ipv4 的很相似,示意咱们在 Ipv6 上监听到了端口 8888。

应用 nc 连贯 socket

咱们曾经建设好了了监听 TCP 连贯的服务器,接下来咱们尝试应用 nc 命令来进行连贯。

nc 是 Ncat 的简称,它是一个十分有用的网络工具,能够做很多事件。咱们来看下本例子中会用到的参数:

  -4                         Use IPv4 only
  -6                         Use IPv6 only
  -v, --verbose              Set verbosity level (can be used several times)
  -z                         Zero-I/O mode, report connection status only

因为须要连贯到 Ipv4 和 Ipv6,所以须要 - 4 和 - 6 参数。

另外咱们须要输入具体的信息,所以须要 - v 参数,最初咱们间接建设连贯,并不发送任何数据,所以这里应用 - z 参数,咱们执行一下来看看成果:

nc -4 -vz 127.0.0.1 8888

看看上面的输入后果:

nc -4 -vz 127.0.0.1 8888
Ncat: Version 7.50 (https://nmap.org/ncat)
Ncat: Connected to 127.0.0.1:8888.
Ncat: 0 bytes sent, 0 bytes received in 0.01 seconds.

能够看到 nc 曾经胜利建设了连贯,并且发送了 0 bytes 的内容。

同样的,咱们建设到 Ipv6 的连贯:

nc -6 -vz ::1 8888

这里的 ::1 示意的是 Ipv6 的本地地址。输入后果如下:

Ncat: Version 7.50 (https://nmap.org/ncat)
Ncat: Connected to ::1:8888.
Ncat: 0 bytes sent, 0 bytes received in 0.01 seconds.

总结

到此,咱们介绍了 Socket 的根本分类 Stream Socket 的含意,并且应用 unix 中的工具搭建了 socket 服务器和客户端,当然这只是最简略的阐明形容, 大家用来领会 Stream Socket 的流程即可。

本文已收录于 http://www.flydean.com/15-stream-socket/

最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!

欢送关注我的公众号:「程序那些事」, 懂技术,更懂你!

退出移动版