详解网络编程基础及同步异步、阻塞非阻塞

一、网络编程基础原理

1.网络编程(Socket)的概念

首先注意, Socket不是Java中独有的概念,而是一个语言无关标准。 任何可以实现网络编程的编程语言都有 Socket

网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个 socket。

建立网络通信连接至少要一个端口号。socket 本质是编程接口(API),对 TCP/IP 的封装, TCP/IP 也要提供可供程序员做网络开发所用的接口,这就是 Socket 编程接口;HTTP 是轿车, 提供了封装或者显示数据的具体形式;Socket 是发动机,提供了网络通信的能力。

Socket 的英文原义是“孔”或“插座”。作为 BSD UNIX 的进程通信机制,取后一种意思。通 常也称作"套接字",用于描述 IP 地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在 Internet 上的主机一般运行了多个服务软件,同时提供几 种服务。每种服务都打开一个 Socket,并绑定到一个端口上,不同的端口对应于不同的服务。 Socket 正如其英文原义那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插 座有一个编号,有的插座提供 220 伏交流电, 有的提供 110 伏交流电,有的则提供有线电 视节目。 客户软件将插头插到不同编号的插座,就可以得到不同的服务。

2.Socket连接步骤
根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三 个步骤:服务器监听,客户端请求,连接确认。【如果包含数据交互+断开连接,那么一共是 五个步骤】

(1)服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连 接的状态,实时监控网络状态。

(2)客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的 套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套 接字的地址和端口号,然后就向服务器端套接字提出连接请求。

(3)连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求, 它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端, 一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接 收其他客户端套接字的连接请求。

(4)数据传输

(5)连接关闭

对于请求连接和关闭连接的三次握手,四次挥手,简图:

关于Tcp/ip三次握手四次挥手的具体流程在这一篇博客有讲解

3.java中的Socket

是在 java.net 包是网络编程的基础类库。其中 ServerSocket 和 Socket 是网络编程的基础类型。ServerSocket 是服务端应用类型。Socket 是建立连接的类型。当连接建立成功后,服务 器和客户端都会有一个 Socket 对象示例,可以通过这个 Socket 对象示例,完成会话的所有 操作。 对于一个完整的网络连接来说,Socket 是平等的,没有服务器客户端分级情况。

二、同步异步与阻塞非阻塞

1.同步和异步是针对应用程序和内核的交互而言的,同步指的是用户进程触发 IO 操作并 等待或者轮询的去查看 IO 操作是否就绪,而异步是指用户进程触发 IO 操作以后便开始做自 己的事情,而当 IO 操作已经完成的时候会得到 IO 完成的通知。 以银行取款为例:

同步 : 自己亲自出马持银行卡到银行取钱(使用同步 IO 时,Java 自己处理 IO 读写);
 异步 : 委托一小弟拿银行卡到银行取钱,然后给你(使用异步 IO 时,Java 将 IO 读写 委托给 OS 处理,需要将数据缓冲区地址和大小传给 OS(银行卡和密码),OS 需要支持异步 IO 操作 API);

同步是主动等待,异步是被动通知

2.阻塞和非阻塞是针对于进程在访问数据的时候,根据 IO 操作的就绪状态来采取的不同 方式,说白了是一种读取或者写入操作方法的实现方式,阻塞方式下读取或者写入函数将一 直等待,而非阻塞方式下,读取或者写入方法会立即返回一个状态值。

以银行取款为例: 阻塞 : ATM 排队取款,你只能等待(使用阻塞 IO 时,Java 调用会一直阻塞到读写完 成才返回);

非阻塞 : 柜台取款,取个号,然后坐在椅子上做其它事,等号广播会通知你办理,没 到号你就不能去,你可以不断问大堂经理排到了没有,大堂经理如果说还没到你就不能去(使 用非阻塞 IO 时,如果不能读写 Java 调用会马上返回,当 IO 事件分发器通知可读写时再继 续进行读写,不断循环直到读写完成)

阻塞是要被挂起,非阻塞是可以去做别的事


---------------------------------------------------------------------

在知乎上看到某大佬的回答,觉得拿过来更方便理解

---------------------------------------------------------------------

1.同步与异步
同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)
所谓同步,就是在发出一个*调用*时,在没有得到结果之前,该*调用*就不返回。但是一旦调用返回,就得到返回值了。
换句话说,就是由*调用者*主动等待这个*调用*的结果。

而异步则是相反,*调用*在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在*调用*发出后,*被调用者*通过状态、通知来通知调用者,或通过回调函数处理这个调用。

典型的异步编程模型比如Node.js

举个通俗的例子:
你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”我查一下",然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。
而异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。

2. 阻塞与非阻塞
阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.

阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

还是上面的例子,
你打电话问书店老板有没有《分布式系统》这本书,你如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果,如果是非阻塞式调用,你不管老板有没有告诉你,你自己先一边去玩了, 当然你也要偶尔过几分钟check一下老板有没有返回结果。
在这里阻塞与非阻塞与是否同步异步无关。跟老板通过什么方式回答你结果无关。

-------------------------------------------

自己总结一下:同步和异步是指我要获取结果的方式,到底我是主动等结果还是被动获取结果。

阻塞和非阻塞就是我在获取结果的这个过程中,我是可以干别的事还是不可以干别的事

发布了227 篇原创文章 · 获赞 77 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/m2606707610/article/details/103398274
今日推荐