一、网络编程概述
同学们,今天我们学习的课程内容叫网络编程。意思就是编写的应用程序可以与网络上其他设备中的应用程序进行数据交互。
网络编程有什么用呢?这个就不言而喻了,比如我们经常用的微信收发消息就需要用到网络通信的技术、在比如我们打开浏览器可以浏览各种网络、视频等也需要用到网络编程的技术。
我们知道什么是网络编程、也知道网络编程能干什么后了,那Java给我们提供了哪些网络编程的解决方案呢?
Java提供的网络编程的解决方案都是在java.net包下。在正式学习Java网络编程技术之前,我们还需要学习一些网络通信的前置知识理论知识,只有这些前置知识做基础,我们学习网络编程代码编写才起来才能继续下去。
首先和同学们聊聊网络通信的基本架构。通信的基本架构主要有两种形式:一种是CS架构(Client 客户端/Server服务端)、一种是BS架构(Brower 浏览器/Server服务端)。
- **CS架构的特点:**CS架构需要用户在自己的电脑或者手机上安装客户端软件,然后由客户端软件通过网络连接服务器程序,由服务器把数据发给客户端,客户端就可以在页面上看到各种数据了。
- **BS架构的特点:**BS架构不需要开发客户端软件,用户只需要通过浏览器输入网址就可以直接从服务器获取数据,并由服务器将数据返回给浏览器,用户在页面上就可以看到各种数据了。
这两种结构不管是CS、还是BS都是需要用到网络编程的相关技术。我们学习Java的程序员,以后从事的工作方向主要还是BS架构的。
二、网络编程三要素
各位小伙伴,我们前面已经知道什么是网络编程了。接下来我们还需要学习一些网络编程的基本概念,才能去编写网络编程的应用程序。
有哪三要素呢?分别是IP地址、端口号、通信协议
- IP地址:表示设备在网络中的地址,是网络中设备的唯一标识
- 端口号:应用程序在设备中唯一的标识
- 协议:连接和数据在网络中传输的规则。
如下图所示:假设现在要从一台电脑中的微信上,发一句“你愁啥?”到其他电脑的微信上,流程如下
1.先通过ip地址找到对方的电脑 2.再通过端口号找到对方的电脑上的应用程序 3.按照双方约定好的规则发送、接收数据
2.1 IP地址
接下来,我们详细介绍一下IP地址。**IP(Ineternet Protocol)全称互联网协议地址,是分配给网络设备的唯一表示。**IP地址分为:IPV4地址、IPV6地址
IPV4地址由32个比特位(4个字节)组成,如果下图所示,但是由于采用二进制太不容易阅读了,于是就将每8位看成一组,把每一组用十进制表示(叫做点分十进制表示法)。所以就有了我们经常看到的IP地址形式,如:192.168.1.66
如果想查看本机的IP地址,可以在命令行窗口,输入ipconfig
命令查看,如下图所示
经过不断的发展,现在越来越多的设备需要联网,IPV4地址已经不够用了,所以扩展出来了IPV6地址。
IPV6采用128位二进制数据来表示(16个字节),号称可以为地球上的每一粒沙子编一个IP地址,
IPV6比较长,为了方便阅读,每16位编成一组,每组采用十六进制数据表示,然后用冒号隔开(称为冒分十六进制表示法),如下图所示
我们在命令行窗口输入ipconfig
命令,同样可以看到ipv6地址,如下图所示
现在的网络设备,一般IPV4和IPV6地址都是支持的。
聊完什么是IP地址和IP地址分类之后,接下来再给大家介绍一下和IP地址相关的一个东西,叫做域名。
我们在浏览器上访问某一个网站是,就需要在浏览器的地址栏输入网址,这个网址的专业说法叫做域名。比如:百度的域名是http://www.baidu.cn
。
域名和IP其实是一一对应的,由运营商来管理域名和IP的对应关系。我们在浏览器上敲一个域名时,首先由运营商的域名解析服务,把域名转换为ip地址,再通过IP地址去访问对应的服务器设备。
关于IP地址,还有一个特殊的地址需要我们记住一下。就是我们在学习阶段进行测试时,经常会自己给自己消息,需要用到一个本地回送地址:127.0.0.1
最后给同学们介绍,两个和IP地址相关的命令
ipconfig: 查看本机的ip地址 pring 域名/ip 检测当前电脑与指定的ip是否连通
ping命令出现以下的提示,说明网络是通过的
2.2 InetAddress类
各位小伙伴,在上一节课我们学习了网络编程的三要素之一,IP地址。按照面向对象的设计思想,Java中也有一个类用来表IP地址,这个类是InetAddress类。我们在开发网络通信程序的时候,可能有时候会获取本机的IP地址,以及测试与其他地址是否连通,这个时候就可以使用InetAddress类来完成。下面学习几个InetAddress的方法。
演示上面几个方法的效果
public class InetAddressTest { public static void main(String[] args) throws Exception { // 1、获取本机IP地址对象的 InetAddress ip1 = InetAddress.getLocalHost(); System.out.println(ip1.getHostName()); System.out.println(ip1.getHostAddress()); // 2、获取指定IP或者域名的IP地址对象。 InetAddress ip2 = InetAddress.getByName("www.baidu.com"); System.out.println(ip2.getHostName()); System.out.println(ip2.getHostAddress()); // ping www.baidu.com System.out.println(ip2.isReachable(6000)); } }
2.3 端口号
端口号:指的是计算机设备上运行的应用程序的标识,被规定为一个16位的二进制数据,范围(0~65535)
端口号分为一下几类(了解一下)
- 周知端口:0~1023,被预先定义的知名应用程序占用(如:HTTP占用80,FTP占用21)
- 注册端口:1024~49151,分配给用户经常或者某些应用程序
- 动态端口:49152~65536,之所以称为动态端口,是因为它一般不固定分配给某进程,而是动态分配的。
需要我们注意的是,同一个计算机设备中,不能出现两个应用程序,用同一个端口号
2.4 协议
各位同学,前面我们已经学习了IP地址和端口号,但是想要完成数据通信还需要有通信协议。
网络上通信的设备,事先规定的连接规则,以及传输数据的规则被称为网络通信协议。
为了让世界上各种上网设备能够互联互通,肯定需要有一个组织出来,指定一个规则,大家都遵守这个规则,才能进行数据通信。
只要按照OSI网络参考模型制造的设备,就可以在国际互联网上互联互通。其中传输层有两个协议,是我们今天会接触到的(UDP协议、TCP协议)
- UDP协议特点
- TCP协议特点
三次握手如下图所示**:目的是确认通信双方,手法消息都是正常没问题的**
四次挥手如下图所示:目的是确保双方数据的收发已经完成,没有数据丢失
三、UDP通信代码(入门案例)
有了网络编程的三要素基础知识之后,我们就可以开始学习编写网络通信的程序了。首先学习基于UDP协议通信的代码编写。
UDP是面向无连接的、不需要确认双方是否存在,所以它是不可靠的协议。Java提供了一个类叫DatagramSocket来完成基于UDP协议的收发数据。使用DatagramSocket收发数据时,数据要以数据包的形式体现,一个数据包限制在64KB以内
具体流程如下图所示:假设我们把DatagramSocket看做是街道两天的人,现在左边的人要扔一盘韭菜到右边,这里的韭菜就是数据,但是数据需要用一个盘子装起来,这里的盘子就是DatagramPacket数据包的意思。通信双方都需要有DatagramSocket(扔、接韭菜人),还需要有DatagramPacket(装韭菜的盘子)
下面我们看一个案例,需要有两个程序,一个表示客户端程序,一个表示服务端程序。
需求:客户端程序发一个字符串数据给服务端,服务端程序接收数据并打印。
3.1 客户端程序
/** * 目标:完成UDP通信快速入门:实现1发1收。 */ public class Client { public static void main(String[] args) throws Exception { // 1、创建客户端对象(发韭菜出去的人) DatagramSocket socket = new DatagramSocket(7777); // 2、创建数据包对象封装要发出去的数据(创建一个韭菜盘子) /* public DatagramPacket(byte buf[], int length, InetAddress address, int port) 参数一:封装要发出去的数据。 参数二:发送出去的数据大小(字节个数) 参数三:服务端的IP地址(找到服务端主机) 参数四:服务端程序的端口。 */ byte[] bytes = "我是快乐的客户端,我爱你abc".getBytes(); DatagramPacket packet = new DatagramPacket(bytes, bytes.length , InetAddress.getLocalHost(), 6666); // 3、开始正式发送这个数据包的数据出去了 socket.send(packet); System.out.println("客户端数据发送完毕~~~"); socket.close(); // 释放资源! } }
3.2 服务端程序
public class Server { public static void main(String[] args) throws Exception { System.out.println("----服务端启动----"); // 1、创建一个服务端对象(创建一个接韭菜的人) 注册端口 DatagramSocket socket = new DatagramSocket(6666); // 2、创建一个数据包对象,用于接收数据的(创建一个韭菜盘子) byte[] buffer = new byte[1024 * 64]; // 64KB. DatagramPacket packet = new DatagramPacket(buffer, buffer.length); // 3、开始正式使用数据包来接收客户端发来的数据 socket.receive(packet); // 4、从字节数组中,把接收到的数据直接打印出来 // 接收多少就倒出多少 // 获取本次数据包接收了多少数据。 int len = packet.getLength(); String rs = new String(buffer, 0 , len); System.out.println(rs); System.out.println(packet.getAddress().getHostAddress()); System.out.println(packet.getPort()); socket.close(); // 释放资源 } }
最新Java基础系列课程--Day15-网络编程(二)https://developer.aliyun.com/article/1423554