Java-网络编程思维导图
网络编程
- 网络基础
- 互联网
- 互联网是网络的网络(internet),即把很多计算机网络连接起来,形成一个全球统一的互联网。
- IP地址
- IPv4和IPv6
- IPv4
- IPv4采用32位地址
- 大约有2^32个(约42亿)目前已经耗尽
- IPv4采用32位地址
- IPv6
- IPv6采用64位地址
- 大约有2^128(约340万亿亿亿亿)个
- IPv6采用64位地址
- IPv4
- 公网和内网
- 公网IP地址
- 可以直接被访问
- 内网IP地址
- 只能在内网访问
- 例如:192.168.x.x 10.x.x.x
- 公网IP地址
- 特殊的IP
- 本机地址
- 127.0.0.1
- 本机地址
- 网络号(network number)
- 网络号 = IP & 子网掩码
- IPv4和IPv6
- 域名
- 因为直接记忆IP地址非常困难,所以我们通常使用域名访问某个特定的服务。域名解析服务器DNS负责把域名翻译成对应的IP,客户端再根据IP地址访问服务器。
- 特殊的域名
- 本机域名localhost 对应的IP:127.0.0.1
- 网络模型
- 应用层
- 功能
- 直接为用户的应用进程(例如电子邮件、文件传输和终端仿真)提供服务
- 应用层协议
- 如支持万维网应用的HTTP协议,
- 支持电子邮件的SMTP协议
- 支持文件传送的FTP协议,DNS,POP3,SNMP,Telnet等等
- 功能
- 传输层
- 功能
- 负责向两个主机中进程之间的通信提供服务
- 复用和分用
- 复用
- 多个应用层进程可同时使用下面运输层的服务
- 分用
- 把收到的信息分别交付给上面应用层中相应的进程
- 复用
- 传输层协议
- TCP
- 面向连接的,数据传输的单位是报文段,能够提供可靠的交付。
- UDP
- 无连接的,数据传输的单位是用户数据报,不保证提供可靠的交付,只能提供“尽最大努力交付”。
- TCP
- 功能
- 网络层
- 功能
- 1、负责为分组交换网上的不同主机提供通信服务。
- 2、选中合适的路由,使源主机运输层所传下来的分组,能够通过网络中的路由器找到目的主机。
- 网络层协议
- IP,ICMP,IGMP,ARP,RARP
- 功能
- 数据链路层
- 功能
- 两个主机之间的数据传输,总是在一段一段的链路上传送的,也就是说,在两个相邻结点之间传送数据是直接传送的(点对点)。
- 数据链路层协议
- PPP
- 用来通过拨号或专线方式建立点对点连接发送数据,使其成为各种主机、网桥和路由器之间简单连接的一种共通的解决方案
- PPP
- 透明
- 含义
- 某一个实际存在的事物看起来却好像不存在一样
- 数据链路层对这些数据来说是透明的
- 功能
- 1、在接收数据时,控制信息使接收端能知道一个帧从哪个比特开始和到哪个比特结束。
- 2、控制信息还使接收端能检测到所收到的帧中有无差错。
- 含义
- 功能
- 物理层
- 功能
- 透明地传送比特流
- 功能
- 应用层
- 互联网
- Socket(套接字)和port(端口号)
- 端口号
- 使用的一个用来标识一台主机的某个应用程序
- 端口号不是计算机实际存在的某个物理位置, 而是一种软件上的抽象。
- 范围:0~65536
- 0~1023
- 特权端口,已经分配给指定的应用程序
- 0~1023
- Socket
- Socket是一个抽象概念,一个应用程序通过一个Socket来建立一个远程连接
- 服务器端
- 它的Socket是指定的IP地址和指定的端口号
- 等待、监听客户端的连接请求
- 客户端
- 它的Socket是它所在计算机的IP地址和一个由操作系统分配的随机端口号
- 需要知道服务器端的主机名和端口号。 客户端试图与服务端指定端口号的应用程序
- 服务器端
- 简单理解
- Socket = IP + Port
- Java提供的接口
- ServerSocket
- 服务端
- Socket
- 客户端
- ServerSocket
- 基本结构
- 1、双方创建套接字
- 2、创建连接到套接字的输入输出流
- 3、按照协议对套接字进行读写操作
- 关闭套接字对象
- Socket是一个抽象概念,一个应用程序通过一个Socket来建立一个远程连接
- 端口号
- TCP编程
- 服务端
- 监听8080端口
- ServerSocket ss = new ServerSocket(8080);
- 等待接收客户端请求
- Socket socket = ss.accept();
- 获取客户端输入流
- InputStream in = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(in); BufferedReader br = new BufferedReader(isr);
- 获取客户端的输入数据
- String str = br.readLine(); System.out.println("客户端数据" + str);
- 将数据输出到客户端
- BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); OutputStream os = socket.getOutputStream(); PrintWriter pw = new PrintWriter(os,true); String info = input.readLine(); pw.println(info);
- 关闭
- 监听8080端口
- 客户端
- 指定请求IP和端口号的服务器
- Socket socket = new Socket("127.0.0.1",8080);
- 获取输入流
- InputStream in = socket.getInputStream(); InputStreamReader is = new InputStreamReader(in); BufferedReader br = new BufferedReader(is);
- 接收控制台的输入
- OutputStream os = socket.getOutputStream(); PrintWriter pw = new PrintWriter(os,true); BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); String info = input.readLine(); pw.println(info);
- 输出服务端信息
- String str = br.readLine(); System.out.println("服务器的信息:" + str);
- 关闭
- 指定请求IP和端口号的服务器
- 服务端
- UDP编程
- 服务端
- 构建Socket对象
- DatagramSocket ds = new DatagramSocket();
- 将数据打包成数据报
- String info = "Hello Python"; byte[] bytes = info.getBytes(); int length = info.length(); InetAddress byName = InetAddress.getByName("localhost"); int port = 8080; DatagramPacket dp = new DatagramPacket(bytes,length,byName,port);
- 发送数据报
- ds.send(dp);
- 构建Socket对象
- 客户端
- 构建Socket对象
- DatagramSocket ds = new DatagramSocket(8080);
- 接收数据
- byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, 1024); ds.receive(dp);
- 提取数据
- byte[] data = dp.getData(); int length = dp.getLength(); String info = new String(data,0,length); System.out.println(info);
- 构建Socket对象
- 服务端
- HTTP编程
- HTTP基础
- HTTP是超文本传输协议,它是基于TCP协议之上的一种请求-响应协议
- HTTP请求(Request)
- POST请求
- 请求行+请求头+请求体(头和体用一个空行分隔)
- 请求行
- POST /* HTTP/1.1 (POST的请求方式,/*是路径, HTTP/1.1是版本号)
- 请求头
- Host:表示请求的域名 User-Agent:表示客户端自身标识信息 Accept:表示客户端能处理的HTTP响应格式 Accept-Language:表示客户端接收的语言
- 请求体
- 报文体,它将一个页面表单中的组件值通过param1=value1¶m2=value2的键值对形式编码成一个格式化串。
- 请求行
- 请求行+请求头+请求体(头和体用一个空行分隔)
- GET请求
- Header
- GET /* HTTP/1.1 (GET的请求方式,/*是路径, HTTP/1.1是版本号) Host:表示请求的域名 User-Agent:表示客户端自身标识信息 Accept:表示客户端能处理的HTTP响应格式 Accept-Language:表示客户端接收的语言
- Header
- POST请求
- HTTP响应(Response)
- Header+Body
- HTTP/1.1 200 OK (HTTP版本 响应代码 响应说明) Content-Type: text/html Content-Length: 133251
Hello
- HTTP/1.1 200 OK (HTTP版本 响应代码 响应说明) Content-Type: text/html Content-Length: 133251
- Header+Body
- HTTP编程
- URL类
- 创建对象
- URL url = new URL("http://www.example.com/path/to/target?a=1&b=2");
- 打开连接
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- 请求参数设置
- conn.setRequestMethod("GET");//请求方式 conn.setUseCaches(false); //内容类型是否可序列化的java对象 conn.setConnectTimeout(5000); // 请求超时5秒
- 设置HTTP头
- conn.setRequestProperty("Accept", "*/*"); conn.setRequestProperty("User-Agent", "Mozilla/5.0 (compatible; MSIE 11; Windows NT 5.1)");
- 连接并发送HTTP请求:
- conn.connect();
- 判断HTTP响应是否200
- if (conn.getResponseCode() != 200) { throw new RuntimeException("bad response"); }
- 获取所有响应Header
- Map<string, list<string="">> map = conn.getHeaderFields(); for (String key : map.keySet()) { System.out.println(key + ": " + map.get(key)); }
- 获取响应内容
- InputStream input = conn.getInputStream(); ...
- 创建对象
- HttpClient类
- 创建一个全局HttpClient实例
- static HttpClient httpClient = HttpClient.newBuilder().build();
- 因为HttpClient内部使用线程池优化多个HTTP连接,可以复用
- static HttpClient httpClient = HttpClient.newBuilder().build();
- GET
- 创建请求对象
- HttpRequest request = HttpRequest.newBuilder(new URI(url))
- 设置Header
- request.header("User-Agent", "Java HttpClient").header("Accept", "*/*")
- 设置超时
- request.timeout(Duration.ofSeconds(5))
- 设置版本
- request.version(Version.HTTP_2).build()
- HttpClient发送
- HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
- 获取图片
- httpClient.send(request, HttpResponse.BodyHandlers.ofByteArray());
- 内容很大,获取InputStream流
- httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream());
- 获取图片
- HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
- HTTP允许重复的Header,因此一个Header可对应多个Value
- Map<string, list<string="">> headers = response.headers().map(); for (String header : headers.keySet()) { System.out.println(header + ": " + headers.get(header).get(0)); } System.out.println(response.body().substring(0, 1024) + "...");
- 创建请求对象
- POST
- 创建请求对象
- String url = "http://www.example.com/login"; String body = "username=bob&password=123456"; HttpRequest request = HttpRequest.newBuilder(new URI(url));
- 设置Header
- request.header("Accept", "*/*") request.header("Content-Type", "application/x-www-form-urlencoded")
- 设置超时
- request.timeout(Duration.ofSeconds(5));
- 设置版本
- request.version(Version.HTTP_2)
- 使用POST并设置Body
- request.POST(BodyPublishers.ofString(body, StandardCharsets.UTF_8)).build();
- HttpClient发送
- HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); String s = response.body();
- 创建请求对象
- 创建一个全局HttpClient实例
- URL类
- HTTP基础