网络编程入门

本次主要介绍网络编程的简单总结,大数据的HDFS原理中RPC协议,Socket 编程,为了更好的学习大数据的内容,这次简单的讲解一下网络编程。
另外本博客会持续更新大数据学习的资料,包括概念,原理,搭建,入门案例,小案例等,感兴趣的童鞋,欢迎关注,多多交流。


本次的网络编程主要分为一下几个部分:

  • 网络编程概述
  • 网络通信三要素
  • 网络模型
  • Socket机制
  • IO通信模型
  • RPC

1. 网络编程概述

网络编程:是指在操作系统,网络管理软件,网络通信协议的管理和协调下,使用计算机编程语言来实现计算机之间的资源共享和信息传递。

对我们来说即如何用编程语言实现计算机网络中不同计算机之间的通信。


2. 网络通信三要素

  • IP地址
    IP地址指的是计算机在网络中的唯一标识,32bit(4字节),一般用“点分十进制”表示,举个例子:192.168.25.101,可以分类:

    • A 类: 第 1 个 8 位表示网络地址。剩下的 3 个 8 位表示主机地址
    • B 类: 前 2 个 8 位表示网络地址。剩下的 2 个 8 位表示主机地址
    • C 类: 前 3 个 8 位表示网络地址。剩下的 1 个 8 位表示主机地址
    • D 类地址用于在 IP 网络中的组播
    • E 类地址保留作研究之用。

    Java编程可采用InetAddress 类来操纵 IP 地址。

public static void main(String[] args) throws UnknownHostException {
   InetAddress localHost = InetAddress.getLocalHost();
   System.out.println(localHost.getHostAddress());
   System.out.println(localHost.getHostName());
}
  • 端口号

    • 用于标识进程的逻辑地址,不同进程的标识;
    • 有效端口: 0-65535,其中 0-1024 系统使用或保留端口。
  • 传输协议
    常见的传输协议有UDP(用户数据报协议)和TCP(传输控制协议)

  • UDP
    • 将数据源和目的封装到数据包中,不需要建立连接。
    • 每个数据报的大小限制在64K以内
    • 因为没连接,不需要可靠的协议
    • 不需要建立连接,传输速度快
  • TCP
    • 建立连接,形成传输数据的通道
    • 在连接中进行大量的数据传输
    • 通过三次握手完成连接,是可靠协议
    • 必须建立连接,效率会稍微低一些

3.网络模型

计算机网络之间以何种规则进行通信,就是网络模型所研究的问题。实际的含义是建立某种模型,实现网络数据的传输,中间会对数据进行多次的封装和拆封,实现最底层的传输要求。

网络模型一般是指 OSI 七层参考模型和 TCP/IP 五层参考模型。
网络编程入门_第1张图片

每一层实现各自的功能和协议,并且都为上一层提供业务功能。为了提供这种业务功能,下一层将上一层中的数据并入到本层的数据域中,然后通过加入报头或报尾来实现该层业务功能,该过程叫做数据封装
用户的数据要经过一次次包装,最后转化成可以在网络上传输的信号,发送到网络上。当到达目标计算机后,再执行相反的数据拆包过程。
网络编程入门_第2张图片
每一层的含义具体如下:

  • 物理层
    主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。
    主要作用是将数据最终编码为用 0、 1 标识的比特流,通过物理介质传输。这一层的数据叫做比特。

  • 数据链路层
    主要将接收到的数据进行 MAC 地址(网卡地址)的封装与解封装。常把这一层的数据叫做帧。这一层常工作的设备是交换机

  • 网络层
    主要将接收到的数据进行 IP 地址的封装与解封装。常把这一层的数据叫做数据包。这一层设备是路由器

  • 传输层
    定义了一些数据传输的协议和端口号。主要将接收的数据进行分段和传输,到达目的地址后在进行重组。常把这一层的数据叫做
  • 会话层
    通过传输层建立数据传输的通路。主要在系统之间发起会话或者接收会话请求。
  • 表示层
    主要进行对接收数据的解释、加密与解密、压缩与解压缩。确保一个系统的应用层发送的数据能被另一个系统的应用层识别。
  • 应用层
    主要是为一些终端应用程序提供服务。 直接面对着用户的。

4. Socket 机制

  • Socket概述
    Socket,又称为套接字, 用于描述 IP 地址和端口。应用程序通常通过 socket向网络发出请求或者应答网络请求。
    Socket 就是为网络编程提供的一种机制:通信两端都有 socket;网络通信其实就是 socket 之间的通信;数据在两个 socket 之间通过 IO 传输。
    网络编程也称作为Socket 编程,套接字编程。Socket 通信是 Client/Server模型。

  • 基于 UDP 协议的 Socket 通信

    • 核心类DategramSocket,发送端代码
// 创建发送端 Socket 服务对象
DatagramSocket dSocket = new DatagramSocket();
// 创建数据,打包数据
String message = "hello ,are u UDP ?";
byte[] bys = message.getBytes();
int length = bys.length;
InetAddress address = InetAddress.getByName("localhost");
int port = 12621;
DatagramPacket dPacket = new DatagramPacket(bys, length, address, port);
// 发送数据
dSocket.send(dPacket);
// 资源释放
dSocket.close();
  • 接收端
//创建接收端 Socket 服务对象
DatagramSocket dSocket = new DatagramSocket(12621);
//创建数据包(接收容器)
byte[] bys = new byte[1024];
DatagramPacket dPacket = new DatagramPacket(bys, bys.length);
//调用接收方法
dSocket.receive(dPacket);
//数据包解析
InetAddress address = dPacket.getAddress();
String hostAddress = address.getHostAddress();
byte[] data = dPacket.getData();
String message = new String(data);
System.out.println(hostAddress+"*********:"+message);
//资源释放
dSocket.close();
  • 基于UDP协议的Socket通信
    • 服务端,核心API :ServerSocket
//建立服务端 socket 服务,并且监听一个端口
ServerSocket ss = new ServerSocket(13131);
//监听连接
Socket s = ss.accept();
//获取输入流, 读取数据
InputStream inputStream = s.getInputStream();
byte[] bys = new byte[1024];
int len = inputStream.read(bys);
System.out.println(new String(bys, 0, len));
//关闭客户端
s.close();
//关闭服务端, 一般服务端不关闭
ss.close();
  • 客户端,核心API:Socket
//创建客户端的 socket 服务,指定目的主机和端口
Socket s = new Socket("127.0.0.1", 13131);
//通过 socket 获取输出流,写数据
OutputStream outputStream = s.getOutputStream();
outputStream.write("hello ,this is tcp?".getBytes());
//释放资源
s.close();

5. IO通信模型

网络通信的本质是网络间的数据 IO。 只要有 IO,就会有阻塞或非阻塞的问题,无论这个 IO 是网络的,还是硬盘的。 原因在于程序是运行在系统之上的任何形式的 IO 操作发起都需要系统的支持。

  • BIO(阻塞模式)
    BIO 即 blocking IO,是一种阻塞式的 IO。jdk1.4 版本之前 Socket 即 BIO 模式。
    BIO 的问题在于 accept()、 read()的操作点都是被阻塞的。

    网络编程入门_第3张图片

    • 原理
      务器线程发起一个 accept 动作,询问操作系统是否有新的 socket 信息从端口 X 发 送过来。 注意,是询问操作系统。 如果操作系统没有发现有 socket 从指定的端口 X 来,那么操作系统就会等待。这样 serverSocket.accept()方法就会一直等待。这就是为什么 accept()方法为什么会阻塞。

    • 线程等待
      如果想让 BIO 同时处理多个客户端请求,就必须使用多线程,即每次 accept阻塞等待来自客户端请求,一旦收到连接请求就建立通信, 同时开启一个新的线程来处理这个套接字的数据读写请求,然后立刻又继续 accept 等待其他客户端连接请求,即为每一个客户端连接请求都创建一个线程来单独处理。

    • 补充
      如果BIO是单线程进行,在大量的客户端请求涌入后,会有部分信息无法处理。所以在多个请求的时候,需要建立多线程。在多线程阻塞情况下,会又大量的连接的产生的关闭,消耗性能。
  • NIO(非阻塞模式)
    NIO 即 non-blocking IO,是一种非阻塞式的 IO。 jdk1.4 之后提供。
    NIO 三大核心部分: Channel(通道), Buffer(缓冲区), Selector(选择器)。
    网络编程入门_第4张图片

    • Buffer: 容器对象,包含一些要写入或者读出的数据。在 NIO 库,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的;在写入数据时,也是写入到缓冲区中。任何时候访问 NIO 中的数据,都是通过缓冲区进行操作。
    • Channel: 通道对象, 对数据的读取和写入要通过 Channel,它就像水管一样。通道不同于流的地方就是通道是双向的,可以用于读、写和同时读写操作。Channel 不会直接处理字节数据,而是通过 Buffer 对象来处理数据。
    • Selector: 多路复用器,选择器。 提供选择已经就绪的任务的能力。 Selector会不断轮询注册在其上的 Channel,如果某个 Channel 上面发生读或者写事件,这个 Channel 就处于就绪状态,会被 Selector 轮询出来,进行后续的 I/O 操作。这样服务器只需要一两个线程就可以进行多客户端通信。
  • 阻塞和非阻塞
    阻塞 IO 和非阻塞 IO 这两个概念是程序级别的。主要描述的是程序请求操作系统 IO 操作后,如果 IO 资源没有准备好,那么程序该如何处理的问题:

    • 阻塞等待;
    • 非阻塞继续执行(Selecter一直轮询,直到有 IO 资源准备好了)。

网络编程入门_第5张图片
网络编程入门_第6张图片

  • 同步和非同步
    同步 IO 和非同步 IO,这两个概念是操作系统级别的。主要描述的是操作系统在收到程序请求 IO 操作后,如果 IO 资源没有准备好,该如何响应程序的问题:
    • 同步IO不响应,直到 IO 资源准备好以后;
    • 非同步IO会返回一个标记(好让程序和自己知道以后的数据往哪里通知),当 IO 资源准备好以后,再用事件机制返回给程序。

6. RPC

  • 什么是RPC
    RPC( Remote Procedure Call Protocol) 远程过程调用协议。

    • 通俗的描述是:客户端在不知道调用细节的情况下,调用存在于远程计算机上的某个过程或函数,就像调用本地应用程序中的一样。
    • 正式的描述是:一种通过网络从远程计算机程序上请求服务,而不需要了解
      底层网络技术的协议。
  • RPC主要特质

    • RPC是协议:协议意味着规范。 目前典型的 RPC 实现包括: Dubbo、Thrift、Hetty 等。 但这些实现往往都会附加其他重要功能,例如 Dubbo 还包括了服务管理、访问权限管理等功能。
    • 网络协议和网络 IO 模型对其透明:既然 RPC 的客户端认为自己是在调用本地对象。那么传输层使用的是 TCP/UDP 还是 HTTP 协议,又或者是一些其他的网络协议它就不需要关心了。既然网络协议对其透明,那么调用过程中,使用的是哪一种网络 IO 模型调用者也不需要关心。
    • 信息格式对其透明: 远程调用过程中, 需要传递一些参数,并且会返回一个调用结果。至于这些参数会以某种信息格式传递给网络上的另外一台计算机,这个信息格式是怎样构成的,调用方是不需要关心的。
    • 跨语言能力:对于调用方来说, 不知道也无需知道远程的程序使用的是什么语言运行的, 无论服务器方使用的是什么语言,本次调用都应该成功,并且返回值也应该按照调用方程序语言所能理解的形式进行描述。
  • RPC原理
    实现 RPC 的程序有5 个部分: User、 User-stub、 RPCRuntime、 Server-stub、 Server。
    网络编程入门_第7张图片

    • 过程描述(类似于网络通信的模式)
      user 就是发起 RPC 调用的 client ,当 user 想发起一个远程调用时,它实际是通过本地调用 user-stub。 user-stub 负责将调用的接口、方法和参数通过约定的协议规范进行编码并通过本地的 RPCRuntime 实例传输到远端的实例。远端 RPCRuntim 实例收到请求后交给 server-stub 进行解码后发起本地端调用,调用结果再返回给 user 端。

权威参考: 《UNIX 网络编程:卷一》第六章——I/O 复用


网络编程的内容简介就到这里结束。
另外本博客会持续更新大数据学习的资料,包括概念,原理,搭建,入门案例,小案例等,感兴趣的童鞋,欢迎关注,多多交流。

你可能感兴趣的:(网路编程,网络模式,网络编程,网络模型,Socket编程,NIO,RPC)