简介

不管是在普通的网络编程中还是在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/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

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

网络协议之:socket协议详解之Socket和Stream Socket的更多相关文章

  1. 常用socket函数详解

    常用socket函数详解 关于socket函数,每个的意义和基本功能都知道,但每次使用都会去百度,参数到底是什么,返回值代表什么意义,就是说用的少,也记得不够精确.每次都查半天,经常烦恼于此.索性都弄 ...

  2. HTTP协议 (六) 状态码详解

    HTTP协议 (六) 状态码详解 HTTP状态码,我都是现查现用. 我以前记得几个常用的状态码,比如200,302,304,404, 503. 一般来说我也只需要了解这些常用的状态码就可以了.  如果 ...

  3. 第8章 应用协议 图解TCP/IP 详解

    第8章 应用协议 图解TCP/IP 详解 8.1 应用层协议概要 应用层协议的定义 TCP和IP等下层协议是不依赖上层应用类型.实用性非常广的协议.而应用协议则是为了实现某种应用而设计和创造的协议. ...

  4. TCP协议粘包问题详解

    TCP协议粘包问题详解 前言 在本章节中,我们将探讨TCP协议基于流式传输的最大一个问题,即粘包问题.本章主要介绍TCP粘包的原理与其三种解决粘包的方案.并且还会介绍为什么UDP协议不会产生粘包. 基 ...

  5. SSL协议之数据加密过程详解

    前言 总括: 原文博客地址:SSL协议之数据加密过程详解 知乎专栏&&简书专题:前端进击者(知乎)&&前端进击者(简书) 博主博客地址:Damonare的个人博客 生活 ...

  6. Socket 死连接详解

    Socket 死连接详解 当使用 Socket 进行通信时,由于各种不同的因素,都有可能导致死连接停留在服务器端,假如服务端需要处理的连接较多,就有可能造成服务器资源严重浪费,对此,本文将阐述其原理以 ...

  7. [转]网络性能评估工具Iperf详解(可测丢包率)

    原文链接:安全运维之:网络性能评估工具Iperf详解:http://os.51cto.com/art/201410/454889.htm 参考博文:http://linoxide.com/monito ...

  8. windows socket函数详解

    windows socket函数详解 近期一直用第三方库写网络编程,反倒是遗忘了网络编程最底层的知识.因而产生了整理Winsock函数库的想法.以下知识点均来源于MSDN,本人只做翻译工作.虽然很多前 ...

  9. Android Socket通信详解

    一.Socket通信简介  Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客 ...

  10. socket接口详解

    1. socket概述 socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信. socket起源于UNIX,在Unix一切 ...

随机推荐

  1. 【C# 线程】线程池 epoll和IOCP之比较

    总结:IOCP :我的打印文件放在店里面排队,轮到我打印了,店长帮我打印一下,打印好了通知我来拿 Epoll  :我的打印文件放在店里面排队,轮到我叫我一下,我自己来打印. 直入正题:Epoll 是L ...

  2. C# init用法

    init是什么意思? init就 modreq([System.Runtime]System.Runtime.CompilerServices.IsExternalInit) 类型的缩写 modreq ...

  3. 安装grunt-browser-sync时报错:“未能加载Visual C++ 组件 “VCBuild.exe”

    报错环境:windows7 X64 , VS2012 报错内容: MSBUILD : error MSB3428: 未能加载 Visual C++ 组件"VCBuild.exe". ...

  4. vue结合webpack打包问题

    在使用vue开发项目时,如果要使用其单文件组件特性,必然要使用webpack或者其他打包工具打包,这里我用到的是webpack打包,首先是搭建vue环境和webpack环境,在这里遇到的一个问题是在成 ...

  5. 小程序根据ID跳转到不同的分页

    想实现效果: 点击后跳转 wxml: <view class="fiveson">         <view class="fiveson-son&q ...

  6. java复习面向对象(二)

    java复习面向对象(二) 1.static关键字 举例图片 静态变量 使用static修饰的成员变量是静态变量 如果一个成员变量使用了关键字static,那么这个变量不属于对象自己,而属于所在的类多 ...

  7. CSS复合选择器,元素的显示模式,CSS背景设置

    欢迎大家去博客冰山一树Sankey,浏览效果更好.直接右上角搜索该标题即可 博客园主页:博客园主页-冰山一树Sankey CSDN主页:CSDN主页-冰山一树Sankey 前端学习:学习地址:黑马程序 ...

  8. Spring源码之九finishRefresh详解

    Spring源码之九finishRefresh详解 公众号搜索[程序员田同学],专职程序员兼业余写手,生活不止于写代码 Spring IoC 的核心内容要收尾了,本文将对最后一个方法 finishRe ...

  9. 2022年官网下安装GIT最全版与官网查阅方法

    目录 安装部署Git 1.百度搜索git,双击进入. 2.进入主页,双击如图位置. 3.进入下载列表,双击下载. 4.找到本地文件位置,双击安装,弹出界面,选择next 5.进入安装路径位置,修改路径 ...

  10. CodeReview规范

    目标和原则 提高代码质量,及早发现潜在缺陷,降低修改/弥补缺陷的成本 促进团队内部知识共享,提高团队整体水平 评审过程对于评审人员来说,也是一种思路重构的过程,帮助更多的人理解系统 是一个传递知识的手 ...