简介

不论是在一般的网络编程中还是在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:80124.225.141.53:443

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

应用socat创立一个TCP服务器

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

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

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

socat -hsocat by Gerhard Rieger and contributors - see www.dest-unreach.orgUsage: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 -hUsage: 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 -tlnState       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 8888Ncat: 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/

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

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