05-网络编程、UDP通信程序、TCP通信程序、commons-io工具包、NIO
1、网络编程
1.1、网络编程的概念
- 什么是网络编程
- 实现在不同计算机上进行数据传输的程序
1.2、网络编程场景
- 网络应用程序、即时通信、网游对战、金融证券、国际贸易、邮件、等等
1.3、常见的软件架构
- Client-Server(CS):客户端-服务端模式
- 客户端
- 在电脑上安装一个软件(客户端)
- 程序开发工作量
- 客户端和服务端都需要大量的工作
- 客户端
- Browser-Server:浏览器-服务器端模式
- 客户端:不需要,只要有浏览器就可以
- 程序员开发工作量:在服务端
1.4、网络编程三要素
1.4.1、IP地址
- 概念
- 指的是互联网协议地址(Internet Protocol Address),俗称IP。IP地址用来给一个网络中的计算机设备做唯一的编号
- 作用
- 通过IP地址可以找到某台电脑
1.4.2、端口号
- 概念
- 应用程序在设备中唯一的标识。通过端口号可以找到电脑上的某个程序
- 注意
- 一个端口号只能被一个应用程序使用
1.4.3、协议
- 概念
- 计算机网络中,连接和通信的规则被称为网络通信协议
- UDP协议特点
- 不需要连接
- 速度快
- 有大小限制(一次最多发送64K)
- 易丢失数据
- UDP协议通信场景(速度要求高,数据完整性要求不高)
- 直播
- 语音通话
- 视频会话
- TCP协议特点
- 需要连接
- 速度慢
- 没有大小限制
- 不易丢失数据
2、UDP通信程序
2.1、概念
- UDP协议通信是不需要连接的,相当于我们生活中的寄快递,直接寄出即可
2.2、DatagramSocket的作用
- 表示UDP的发送端和接收端
- send()发送数据,receive()接收数据
2.3、DatagramPacket
- 表示数据包
- DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)
- 创建发送的数据包
2.4、InetAddress的使用
- static InetAddress getLocalhost()
- 获取本机的IP地址对象
- public static InetAddress getByName(String host)
- 确定主机名称的IP地址,主机名称可以是机器名称,也可以是IP地址
- public String getHostName()
- 获取此IP地址的主机名
- public String getHostAddress()
- 返回文本显示中的IP地址字符串
3、TCP通信程序
3.1、 TCP通信概念
- TCP协议通信是需要连接的,建立连接后以流的形式传输。相当于打电话
3.2、编写TCP客户端
-
步骤
- 1.创建客户端
- 2.得到输入流读取数据
- 3.得到输出流写数据
- 4.关闭资源
-
Demo
-
System.out.println("客户端启动啦!"); // 1.创建客户端, 创建好的客户端会自动连接 "127.0.0.1" 这台电脑的 10086端口 Socket socket = new Socket("127.0.0.1",10086); // 2.得到输出流写数据 OutputStream out = socket.getOutputStream(); out.write("你只能靠你自己".getBytes()); // 3.得到输入流读取数据 InputStream in = socket.getInputStream(); byte [] buf = new byte[1024]; int len = in.read(buf); System.out.println("客户端收到:" + new String(buf, 0, len)); // 4.关闭资源 in.close(); out.close(); socket.close();
3.3、编写TCP服务端
-
步骤
- 1.创建TCP服务端
- 2.同意客户端的请求
- 3.得到输入流读取数据
- 4.得到输出流写数据
- 5.关闭资源
-
Demo
-
System.out.println("服务端启动啦!"); // 1.创建TCP服务端, 创建的服务端会使用本机的10086端口,将来别的程序通过10086端口就能找到这个服务端 ServerSocket serverSocket = new ServerSocket(10086); // 2.同意客户端的请求 Socket accept = serverSocket.accept(); // 3.得到输入流读取数据 InputStream in = accept.getInputStream(); byte [] buf = new byte[1024]; int len = in.read(buf); System.out.println("服务端收到" + new String(buf, 0, len)); // 4.得到输出流写数据 OutputStream out = accept.getOutputStream(); out.write("老地方见".getBytes()); // 5.关闭资源 out.close(); in.close(); accept.close(); serverSocket.close();
3.4、文件上传案例
3.4.1、理解TCP文件上传流程
- 客户端读取本地文件,通过Socket流发送给服务端。服务端读取Socket流中的数据,写到文件中
3.4.2、编写TCP文件上传客户端
-
上传客户端编写流程
- 1.创建客户端
- 2.创建文件输入流
- 3.得到Socket的输出流
- 4.循环读写数据
- 5.得到Socket输入流读取数据
- 6.关闭资源
-
上传服务端编写流程
- 1.创建服务端
- 2.同意客户端的连接
- 3.得到Socket输入流
- 4.创建文件输出流
- 5.循环读写数据
- 6.得到Socket的输出流写数据
- 7.关闭资源
-
解决服务端无法停止问题
-
while ((len = fis.read()) != -1){ out.write(buf , 0 ,len); } System.out.println("客户端上传成功"); socket.shutdownOutput(); //让客户端Socket的输出流结束
-
3.4.3、如何支持多人上传
-
while(true) { serverSocket.accept(); } // 支持多人"同时"上传 // 多线程
4、commons-io工具包
4.1、commons-io概述
- commons-io是apache开源基金组织提供的一组有关IO操作的类库,可以提高IO功能开发的效率
- commons-io工具包提供了很多有关io操作的类。有两个主要的类FileUtils,IOUtils
4.2、commons-io使用
- String readFileToString(File file, String encoding)
- 读取文件中的数据,返回字符串
- void copyFile(File srcFile, File destFile)
- 复制文件
- void copyDirectoryToDirectory(File srcDir, File destDir)
- 复制文件夹
4.3、commons-io使用步骤
- 1.导入commons-io-x.x.jar包
- 2.在项目中创建一个文件夹:lib
- 3.将commons-io-2.6.jar文件复制到lib文件夹
- 4.在jar文件上点击右键,选择Add as Library -> 点击OK
- 5.在类中导包使用
5、NIO
5.1、概述
- JDK1.4以前:InputStream/OutputStream称为BIO(Blocking IO)阻塞式IO
- JDK1.4推出了一套新的IO体系称为NIO(New IO/Not Blocking IO)非阻塞式IO
5.2、阻塞和非阻塞的概念
- 阻塞
- 如果没有数据就一直等待
- 非阻塞
- 如果没有数据,不会一直等待,可以做其他事情
5.3、NIO 3个角色
- Channel(通道)可以双向传输数据
- ByteBuffer相当于之前BIO的byte[],可以保存要发送和接收的数据,ByteBuffer效率比byte[]要高,功能更强大
- Selector选择器,可以管理多个连接