概述
- 下面给了两个链接,是关于OSI模型和TCPIP模型
网络要素
IP地址
- 网络中设备的标识
- 不易记忆,可用主机名
- 本地回环地址:127.0.0.1 主机名:localhost
IP对象
1 | public static void main(String[] args) throws UnknownHostException { |
端口号
- 用于标识进程的逻辑地址,不同进程的标识
- 有效端口:0~65535,其中0~1024为系统保留端口
传输协议
- 通讯的规则
- 常见协议:TCP,UDP
UDP
- 将数据及源和目的封装在数据包内,不需要建立连接
- 将每个数据包大小限制在64K内
- 无连接,是不可靠协议
- 不需建立连接,所以速度快
TCP
- 建立连接,形成传输数据的通道
- 在连接中进行大数据量传输
- 通过三次握手完成连接,可靠协议
- 必须建立连接,效率会稍低
域名解析
- DNS( Domain Name System)是“域名系统”的英文缩写
- 它用于TCP/IP网络,提供的服务是用来将主机名和域名转换为IP地址的工作
- 当输入一个域名时,会先在本地的hosts下解析,如果没有就通过DNS解析为IP地址
屏蔽恶意网站原理
- 在本地 C:\Windows\System32\drivers\etc 目录下,有一个hosts文件
- 在最后面加上 127.0.0.1 www.xxxxx.com
- 那么这个网站就会被屏蔽掉了
socket编程
UDP协议
发送端
- 思路
- 1,建立UDP的socket服务
- 2、将要发送的数据封装到数据包中
- 3、通过UDP的socket服务将数据包发送出去
- 4、关闭socket服务
1 | public static void main(String[] args) throws IOException { |
接收端
- 思路:
- 1、建立UDP socket服务,因为是要接收数据,必须要明确一个端口号
- 2、创建数据包,用于存储接收到的数据。方便用数据包对象的方法解析这些数据
- 3、使用socket服务的receive方法将接收的数据存储到数据包中
- 4、通过数据包的方法解析数据包中的数据
- 5、关闭资源
1 | public static void main(String[] args) throws IOException { |
- 先开启接收端,再开启发送端
- 注意:发送端的DatagramPacket和接收端的DatagramSocket 端口需要一致
TCP协议
客户端
- 客户端发数据到服务端
- TCP传输,客户端建立的过程:
- 1、创建TCP客户端socket服务。使用的是Socket对象,建议该对象一创建就明确目的地,要连接的主机
- 2、如果连接建立成功,说明数据传输通道已建立。该通道就是socket流 ,是底层建立好的。
- 既然是流,说明这里既有输入,又有输出。想要输入或者输出流对象,可以找Socket来获取。
- 可以通过getOutputStream(),和getInputStream()来获取两个字节流。
- 3、使用输出流,将数据写出
- 4、关闭资源
1 | public static void main(String[] args) throws UnknownHostException, IOException { |
服务端
- 服务端接收客户端发送过来的数据,并打印在控制台上。
- 建立TCP服务端的思路:
- 1、创建服务端socket服务。通过ServerSocket对象。
- 2、服务端必须对外提供一个端口,否则客户端无法连接
- 3、获取连接过来的客户端对象
- 4、通过客户端对象获取socket流读取客户端发来的数据,并打印在控制台上
- 5、关闭资源。关客户端,关服务端
1 | public static void main(String[] args) throws IOException { |
练习一
需求
- 客户端输入字母数据,发送给服务端,服务端收到后显示在控制台,
- 并将该数据转成大写返回给客户端,直到客户端输入over.转换结束.
- 创建一个英文大写转换服务器
- 分析:
- 有客户端和服务端,使用TCP传输
客户端编写
- 客户端思路:
- 1、需要先有socket端点
- 2、客户端的数据源:键盘
- 3、客户端的目的:socket
- 4、接收服务端的数据,源:socket
- 5、将数据显示在打印出来:目的:控制台
- 6、在这些流中操作的数据,都是文本数据
- 转换客户端思路:
- 1、创建socket客户端对象
- 2、获取键盘录入
- 3、将录入的信息发送给socket输出流
1 | public static void main(String[] args) throws UnknownHostException, IOException { |
服务端编写
- 转换服务端思路:
- 1、ServerSocket服务
- 2、获取socket对象
- 3、源:socket,读取客户端发过来的需要转换的数据
- 4、目的:显示在控制台上
- 5、将数据转成大写发给客户端
1 | public static void main(String[] args) throws IOException { |
常见问题
- 如果将这两段代码中的PrintWriter 的true删掉,也就是不让他自动刷新
- 再将out.println(line) 及 out.println(line.toUpperCase())注释掉,
- 改写为out.print(xxx); 运行代码试试
- 是否发现客户端输入后,服务端没显示,客户端也不能继续输入了?
- 这是因为堵塞了,没有刷新
- 加上out.flush()再试试?还是不行
- 没有换行符没法终止,服务端认为客户端没有输入完整
- 一定注意,需要换行和刷新,PrintWriter 的true,System.out.println(xxx)
练习二
需求
- 客户端发送服务端文本文件,服务端接收到后,返回接收成功
客户端编写
- 思路:
- 1、创建一个socket端点
- 2、客户端的数据源:硬盘文件
- 3、客户端的目的:socket
- 4、接收服务端的数据,源:socket
- 5、将数据显示在打印出来:目的:控制台
1 | public static void main(String[] args) throws UnknownHostException, IOException { |
服务端编写
- 服务端思路:
- 1、ServerSocket服务
- 2、获取socket对象
- 3、源:socket,读取客户端发过来的文件数据
- 4、目的:硬盘,存放在指定目录下
- 5、返回客户端:上传成功
1 | public static void main(String[] args) throws IOException { |
练习三
需求
- 多客户端进行上传图片操作,服务端接收后并回复
客户端
1 | public class UploadPicClient { |
服务端
- 因为是多客户端,所以需要用多线程
- 否则,一个客户端传文件时,别的客户端只能等待
1 | public class UploadTask implements Runnable { |
客户端服务端原理
模拟服务器
- 为了了解原理,自定义一个服务器
1 | public class MyTomcat { |
- 打开浏览器,输入localhost:9090,页面显示嘎嘎嘎嘎
- 控制台显示:
1 | 0:0:0:0:0:0:0:1.....connected |
- 解释:
1 | GET / HTTP/1.1 请求行 请求方式 http协议版本。 |
模拟浏览器
1 | public class MyBrowser { |
- 开启模拟服务器后,再开启模拟浏览器
- 模拟浏览器可以看到嘎嘎嘎嘎,模拟服务器也收到了浏览器传来的数据
URL
- 获取URL对象的URL连接器对象。将连接封装成了对象:
- Java中内置的可以解析的具体协议的对象+socket
1 | URLConnection conn = url.openConnection(); |
常用网络结构
C/S
- client/server(客户端、服务端)
- 特点:
- 该结构的软件,客户端和服务端都需要编写
- 可发成本较高,维护较为麻烦
- 好处:
- 客户端在本地可以分担一部分运算
B/S
- browser/server(浏览器、 服务端)
- 特点:
- 该结构的软件,只开发服务器端,不开发客户端,因为客户端直接由浏览器取代。
- 开发成本相对低,维护更为简单
- 缺点:
- 所有运算都要在服务端完成