1、网络编程的概念

计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
网络编程不等于网站编程,网络编程即使用套接字来达到进程间通信,现在一般称为TCP/IP编程。


2、网络编程的目的

直接或间接地通过网络协议与其它计算机实现数据交换,进行通讯。

3、网络编程三要素

3.1 IP地址和端口号

(IP地址)

  1. ip地址为唯一的标识Internet上的计算机
  2. ip地址分类方式:IPV4和IPV6方式

IPV4:4个子节组成,4个0~255组成,例如192.168.0.1
IPV6:6个子节组成,写成8个无符号整数,例如 3ffe:3201:1401:1280:c8ff:fe4d:db39:1984
(端口号)

  1. 标识计算机上正在运行的进程,不同的进程拥有不同的端口号
  2. 端口号分类:

公认端口:0~1023。被预先定义的服务通信占用(如:HTTP占用端口 80,FTP占用端口21,Telnet占用端口23)
注册端口:1024~49151。分配给用户进程或应用程序。(如:Tomcat占 用端口8080,MySQL占用端口3306,Oracle占用端口1521等)。
动态/私有端口:49152~65535。
(InetAddress类)

  1. 计算机表示主机地址有两种表达方式:

1.1 域名地址,例如www.baidu.com
1.2 ip地址,例如 192.168..0.1

  1. InetAddress类对象含有一个Internet主机地址的域 名和iP地址
  2. 当连接网络传输时,输入域名地址后,域名解析器(DNS)负责将域名地址解析为ip地址,和主机建立联系。—域名解析过程
  3. 域名解析过程:

在浏览器输入域名地址,例如输入www.baidu.com,DNS会对这个域名进行解析
step1:浏览器首先会检查自身缓存中有没有该域名解析的地址,如果有,直接解析完成,如果没有,则进行下一步。
step2:当浏览器中没有缓存域名解析的地址时,操作系统会检查系统中的缓存是否有该域名解析的ip地址,如果有,直接调用解析完成,在windows中通常可以使用 C:\Windows\System32\drivers\etc\hosts来进行设置,可以将任意域名解析到任意IP地址。
step3:如果系统中没有缓存域名解析的地址时,操作系统会把域名地址发送给域名服务器(LDNS)LDNS一般提供给用户本地互联网的DNS解析服务。LDNS也有缓存域名解析结果,大部分域名请求都会在这层完成。
step4:如果LDNS没有完成域名解析,那么会将域名地址发送给根域名服务器进行解析。
step5:根域名服务器会返回给LDNS所查询域的主域名服务器地址(GTLD)
step6:本地域名服务器再向第五步得到的GTLD地址发送请求 。
step7:接受请求的GTLD服务器查找并返回此域名对应的Name Server域名服务器的地址,Name Server通常就是你注册的域名服务器,你的域名服务提供商 的服务器。
step8:Name Server域名服务器会查询存储在其服务器的域名和IP地址映射关系表,连同一个TTL值返回个DNS 域名服务器。
step9:返回该域名对应的IP地址和TTL值,LDNS服务器会缓存这个域名和对应的IP地址,缓存时间由一起返回的TTL值确定。
step10:DNS服务器将解析的结果返回给用户,依据TTL值缓存在本地系统以及浏览器中,到此域名解析基本完成了。

★3.2 网络通信协议(TCP/IP协议)

3.2.1TCP/IP协议的基本概念

传输控制协议/因特网互联协议(Transmission Control Protocol/Internet Protocal),是Internet最基本、最广泛的协议。它定义了计算机如何连入因特网[IP协议],以及数据如何在它们之间传输的标准[TCP协议]。它的内部包含一系列的用于处理数据通信的协议,并采用了4层的分层模型,每一层都呼叫它的下一层所提供的协议来完成自己的需求。
速率传输代码代码结构传输控制步骤出错控制等制定标准。
image.png

3.2.2TCP/IP网络通信四层模型

由于结点之间联系很复杂,在制定协议时,把复杂成份分解成一些简单的成份,再将它们复合起来。最常用的复合方式就是层次方式,及同层间可以通信,上一层可以调用下一层,而与再下一层不发生关系。各层互不影响,利于系统的开发和扩展。
image.png
不难看出,TCP/IP 与 OSI 在分层模块上稍有区别。OSI 参考模型注重“通信协议必要的功能是什么”,而 TCP/IP 则更强调“在计算机上实现协议应该开发哪种程序”。

应用层:主要负责应用程序的协议,例如HTTP协议、FTP协议等。
传输层:主要使网络程序进行通信,在进行网络通信时,可以采用TCP协议,也可以采用UDP协议
网络层:网络层是整个TCP/IP协议的核心,它主要用于将传输的数据进行分组,将分组数据发送到目标计算机或者网络。
数据链路层:链路层是用于定义物理传输通道,通常是对某些网络连接设备的驱动协议,例如针对光纤、网线提供的驱动。

3.2.3 传输层TCP协议、UCP协议详解

由于我们的程序一般都在应用层,所以我们需要对传输层进行分析,与应用层打交道
java.net包中提供了两种常见的网络协议的支持:TCP和UDP
1、TCP协议

  1. - **传输控制协议**(Transmission Control Protocol)。
  2. - TCP协议是面向连接的通信协议,即传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。

基于TCP实现通信一般有两种方式:
1、通过端口号来识别应用
2、通过ip地址、端口号、通信协议号来识别应用

     - TCP连接能够实现大量的数据传输
     - 在TCP连接中必须要明确客户端与服务器端,由客户端向服务端发出连接请求,每次连接的创建都需要经过“**三次握手**”。
     - 三次握手详解:
                 - ![image.png](https://cdn.nlark.com/yuque/0/2021/png/21962920/1631084265582-54f012db-e1b0-4451-9f33-dbd20022d0c4.png#clientId=u1c16b38c-7618-4&from=paste&height=344&id=u52a8094c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=459&originWidth=581&originalType=url&ratio=1&size=209380&status=done&style=none&taskId=u01130252-50c6-4c08-85bb-fb1a8ff9194&width=436)
     - 传输完成后需释放已经建立的连接,断开需要经过**“四次挥手”**
     - **“四次挥手详解:”**

image.png
step1:客户端想要关闭连接,此时会发送一个TCP首部Fin标志位被置为1的报文(即Fin报文),之后客户端进入Fin_WAIT_1状态
step2:服务器端接收到客户端发送的Fin报文,就向客户端发送ACK应答报文,之后服务器端进入Closed_WAIT状态
step3:客户端收到服务器端发送的ACK报文之后,进入Fin_WAIT_2状态
step4:服务器端处理完数据传输后,也想客户端发送一个Fin报文,之后服务端进入LAST_ACK状态
step5:客户端收到Fin报文,就向服务端发送ACK应答报文,之后客户端进入TIME_WAIT状态
step6:服务端收到客户端发送的ACK报文之后,就进入Close状态,此时服务端已关闭连接。
step7:客户端在经过2msl一段时间后,自动进入close状态,此时客户端已关闭连接。

2、UDP协议:

     - **用户数据报协议**(User Datagram Protocol)。
     - UDP是无连接通信协议,即在数据传输时,**数据的发送端和接收端不建立逻辑连接。**简单来说,当一台计算机向另外一台计算机发送数据时,发送端不会确认接收端是否存在,就会发出数据,同样接收端在收到数据时,也不会向发送端反馈是否收到数据
     - 使用UDP协议消耗资源小,通信效率高,所以通常都会用于**音频、视频和普通数据的传输**例如视频会议都使用UDP协议。

3.3 Socket编程(套接字编程)

  -  网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标 识符套接字。  
  - 网络通信本质为Socket间的通信,通信的两端都需要有Socket,是两台机器间通信的端点。

image.png

(一)基于Socket的TCP网络编程
基本步骤:
1、创建Socket对象:客户端根据服务端的ip地址及端口号创建一个Socket对象,若服务器响应,则成功建立客户端到服务端的网络通信。
2、打开连接到Socket的输入/输出流:使用getInputStream()/getOutputStream()获得输入流和输出流,实现客户端和服务端之间的数据传输。例如客户端发送数据给服务端,那么客服端使用getOutputStream()实现数据的传输,服务端使用getInputStream()对客户端数据的读取。
3、 按照一定的协议对 Socket 进行读/写操作:通过输入流读取服务器放入线路的信息 (但不能读取自己放入线路的信息),通过输出流将信息写入线程。
4、关闭Socket:关闭客户端到服务端的连接,释放线路
相关类:
1、Socket类:主要是针对客户端,实例化一个Socket类,创建一个客户端对象,向服务端发出连接请求,服务端响应请求,两者建立连接开始通信。
2、ServerSocket类主要是针对服务端,实例化一个ServerSocket,即创建一个服务端对象,相当于开启一个服务,等待客户端来进行连接。
(二) UDP网络编程
基本步骤:
1、发送端:

              - 创建一个DatagramSocket对象,作为数据的发送端对象。
              - 创建一个DatagramPacket对象包,确定要发送的数据及数据发送的对象(ip地址和端口号)。
              - 调用DatagramSocket.send()方法,将packet包发送
              - 释放资源对象

2、接收端:

              - 创建一个DatagramSocket对象,作为数据的接收端对象(需指定端口号)
              - 创建一个DatagramPacket对象包,用于接收发送端发送过来的数据。
              - 调用DatagramSocket.receive()方法,接收数据(阻塞式接收)
              - 将接受到的数据包转换为字符串输出
              - 释放资源

相关类:
1、 DatagramPacket 对象封装了UDP数据报,在数据报中包含了发送端的IP 地址和端口号以及接收端的IP地址和端口号 。
2、 UDP数据报通过数据报套接字 DatagramSocket 发送和接收,系统不保证 UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。
(三) URL网络编程
url资源地址基本结构
<传输协议>://<主机名>:<端口号>/<文件名>#片段名?参数名
利用url实现资源下载的基本步骤:
1、创建一个url对象,确定要下载的资源地址
2、连接url,连接到这个资源http,调用openStream(),从网络上读取数据
3、创建一个输入流,实现对访问的资源的读取
4、创建一个输出流,保存读取的资源数据。
5、释放资源。