网络编程
一、网络基础回顾
1). IP: 所谓的IP其实就是计算机的地址,相当于是人的身份证;前提是IPV4协议的话,
构成是4位的.
例如:10.2.26.13,最多能有42亿多的ip地址;每个位置上的数字:【0,255】,
但是边界值不要用,
那为什么却还够我们使用呢?
因为一种技术叫做DHCP,动态获取ip技术;在众多的IP中比较特殊的
IP: 127.0.0.1==localhost 本机的IP
2). 端口: 是计算机出厂的时候,预留的进行内部处理与外部交互的一个“门”,他的取值
是0-65536之间,0-1024之间是特权端口。
例如:http:80 ,ftp:21
3). 协议: 起到一个规范和约束(数据的传输的格式)的作用的一个东西
3.1) 常见的协议: HTTP/HTTPS:超文本传输协议, 例如:浏览器请求
FTP: 文本传输协议
TCP/IP: IP协议 规定了你的IP是怎样的
POP3: 邮件发送协议
XX: 自定义协议
4).网络传输的媒介和载体:
4.1媒介和载体: 网络(
网线: 普通的双绞线(8根)
交换机: 进行信息交换的一个工具,但是不能自动拨号
路由器: 能够实现自动拨号的一个工具,
wifi:
网卡: 是计算机中一个硬件,其主要作用是将数据通过它传
递出去,笔记本中一般是两块网卡,其分别为有线网卡和无线网卡)
PS:网线:普通的双绞线<<绝缘双绞线
8根细线构成的
5) .网络七层: OSI模型:物 数 网 传 会 表 应
即:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。
OSI是一个开放性的通信系统互连参考模型,它是一个定义得非常好的协议规范。
OSI模型有7层结构,每层都可以有几个子层。
二、网络编程概念
1.什么是网络编程
网络编程从大的方面说就是对信息的发送到接收,中间传输为物理线路的作用。
网络编程最主要的工作就是在发送端把信息通过规定好的协议进行组装包,在接收
端按照规定好的协议把包进行解析,从而提取出对应的信息,达到通信的目的。中间最主
要的就是数据包的组装,数据包的过滤,数据包的捕获,数据包的分析,当然最后再做一
些处理,代码、开发工具、数据库、服务器架设和网页设计这5部分都要接触
ps:
简而言之所谓的网络编程就是指在同一网络或者不同网络中的计算机之间的数据
的交换
2.概念与常识
2.1) 协议(Protocol):
是网络编程中一个非常重要的概念,指的是传输数据的格式。因为大家在网络中需要传
输各种各样的信息,在程序中获得到的都是一组数值,如何阅读这些数值呢,就需要提前规
定好这组数据的格式,在客户端按照该格式生成发送数据,服务器端按照该格式阅读该数据,
然后在按照一定的格式生成数据反馈给客户端,客户端再按照该格式阅读数据。现实中类似的
例子就是电报编码,每个数字都是用特定的数据表达。
一般程序的协议都分成客户端发送的数据格式,以及服务器端反馈的数据格式,客户端
和服务器端都遵循该格式生成或处理数据,实现两者之间的复杂数据交换。
ps:
简而言之所谓的协议就是指一种规则
2.2) 端口的概念
为了在一台设备上可以运行多个程序,人为的设计了端口(Port)的概念,类似的例子是
公司内部的分机号码。
规定一个设备有216个,也就是65536个端口,每个端口对应一个唯一的程序。每个网络
程序,无论是客户端还是服务器端,都对应一个或多个特定的端口号。由于0-1024之间多被
操作系统占用,所以实际编程时一般采用1024以后的端口号。
使用端口号,可以找到一台设备上唯一的一个程序。
所以如果需要和某台计算机建立连接的话,只需要知道IP地址或域名即可,但是如果想和
该台计算机上的某个程序交换数据的话,还必须知道该程序使用的端口号
ps:
简而言之所谓的端口就是计算机与外部进行数据交互的一个门
三、网络交互
1.ajax跨域请求
什么是Ajax:
是指一种创建交互式网页应用的网页开发技术
是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术
ps:
简而言之就是异步无刷新的获取数据的一种技术
2.序列化与反序列化
2.1基础概念
导读:
在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,
以便长期保存。比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,
就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion
先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数
据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,
才能在网络上传送;接收方则需要把字节序列再恢复为Java对象.
ps:
对象的序列化主要有两种用途:
1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
常见的序列化格式: 二进制格式,字节数组,json字符串,xml字符串
2) 在网络上传送对象的字节序列
1. 什么是序列化和反序列化:
1>. 序列化: 即seriallization,其意思为把对象转换为字节序列的过程称为对
象的序列化。
2>. 反序列化: 即deseriallization,其意思为把字节序列恢复为对象的过程称
为对象的反序列化
2. 序列化的好处:
1) 永久性保存对象,保存对象的字节序列到本地文件或者数据库中;
2) 通过序列化以字节流的形式使对象在网络中进行传递和接收;
3)通过序列化在进程间传递对象
3. 几种常见的序列化和反序列化协议
互联网早期的序列化协议主要有COM和CORBA。
COM主要用于Windows平台,并没有真正实现跨平台,另外COM的序列化的原理
利用了编译器中虚表,使得其学习成本巨大(想一下这个场景, 工程师需要是简单
的序列化协议,但却要先掌握语言编译器)。由于序列化的数据与编译器紧耦合,扩
展属性非常麻烦。
CORBA是早期比较好的实现了跨平台,跨语言的序列化协议。COBRA的主要问题
是参与方过多带来的版本过多,版本之间兼容性较差,以及使用复杂晦涩。这些政治
经济,技术实现以及早期设计不成熟的问题,最终导致COBRA的渐渐消亡。J2SE1.3
之后的版本提供了基于CORBA协议的RMI-IIOP技术,这使得Java开发者可以采用纯
粹的Java语言进行CORBA的开发
当下比较流行的序列化协议,包括XML、JSON、Protobuf、Thrift和Avro
4. JDK类库中序列化和反序列化API
1) java.io.ObjectOutputStream表示对象输出流;
它的writeObject(Object obj)方法可以对参数指定的obj对象进行序
列化,把得到的字节序列写到一个目标输出流中;
2) java.io.ObjectInputStream表示对象输入流;
它的readObject()方法读取字节序列,再把它们反序列化成为一个对象,
并将其返回
注意:我们根据这个能写出一个工具类: ByteAndObjUtils.java
工具类ByteAndObjectUtils.java
package com.rj.bd;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* @desc java实现序列化的工具类
* @author HYZ
* @time 2021年1月20日
*/
public class ByteAndObjectUtils {
/**
* @desc 将对象转变为字节数组
* @param obj
* @return
* @throws IOException
*/
public byte[] objectToByte(Object obj) throws IOException{
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(obj);//将obj对象序列化并写入到流中
byte[] byt = bo.toByteArray();//将流转变为字节数组
bo.close();
oo.close();
return byt;
}
/**
* @desc byte[]数组转对象
* @param bytes
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
public Object byteToObject(byte[] bytes)
throws IOException, ClassNotFoundException{
ByteArrayInputStream bi = new ByteArrayInputStream(bytes);
ObjectInputStream oi = new ObjectInputStream(bi);
Object obj = oi.readObject();
oi.close();
bi.close();
return obj;
}
}
5. java中的对象要想进行序列化和反序列化:
实现序列化的要求
只有实现了Serializable或Externalizable接口的类的对象才能被序列
化,否则抛出异常(当然这个实现可以是类对象直接的实现也可以是间接的实现)
3.将对象数据与字节数组之间的转换(对象的序列化和反序列化)
1.先创建一个User类对象,且是实现了Serializable接口
2.在创建一个测试类Test.java,在该类中进行序列化和反序列化的操作
代码展示: User.java与Test.java
package com.rj.bd;
import java.io.Serializable;
/**
* @desc 普通的User对象,目的是为了演示对象的序列化与反序列化
* @author HYZ
* @time 2021年1月20日
*/
@SuppressWarnings("serial")
public class User implements Serializable{
public int id;
public String name;
public String code;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public User(int id, String name, String code) {
this.id = id;
this.name = name;
this.code = code;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", code=" + code + "]";
}
public User() {
}
}
package com.rj.bd;
import java.io.IOException;
/**
* @desc 测试类:对象的序列化与反序列化
*
*/
public class Test{
public static void main( String[] args ) throws IOException, ClassNotFoundException{
User user = new User(1,"杨过","98");
//序列化工具类的调用
ByteAndObjectUtils byteAndObjectUtils = new ByteAndObjectUtils();
//将对象转变为序列序列化数组
byte[] bytes = byteAndObjectUtils.objectToByte(user);
for (byte b : bytes) {
System.out.println(b);
}
System.out.println("长度:"+bytes.length);
//将序列化数组转变为对象
User result = (User) byteAndObjectUtils.byteToObject(bytes);
System.out.println(result);
}
}
4.将数据序列化为json格式
1.先创建一个User类对象,且是实现了Serializable接口(与上一个User一致)
2.在创建一个测试类Test.java,在该类中进行序列化和反序列化的操作
代码展示: Test.java
package com.rj.bd.json;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* @desc 测试类:测试将对象序列化为json格式的数据和json格式的数据反序列化为对象
* @author HYZ
* @time 2021年1月20日
*/
public class Test {
public static void main(String[] args) throws
JsonGenerationException, JsonMappingException, IOException {
User userToJson = new User(1,"杨过","98");
//1.将对象序列化为json格式的数据
ObjectMapper mapper = new ObjectMapper();
String jsonStr = mapper.writeValueAsString(userToJson);
System.out.println(jsonStr);
//2.将Json格式的数据反序列化为对象
User jsonToUser = mapper.readValue(jsonStr, User.class);
System.out.println(jsonToUser);
}
}
5.将数据序列化到文本中保存
1.先创建一个User类对象,且是实现了Serializable接口(同样与上一个User一致)
2.在创建一个测试类Test.java,在该类中进行序列化和反序列化的操作
代码展示:Test.java
package com.rj.bd.commons;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.io.FileUtils;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* @desc 将数据对象序列化为json格式,且保存到txt文件中
* @author HYZ
* @time 2021年1月20日
*/
public class Test {
public static void main(String[] args) throws
JsonGenerationException, JsonMappingException, IOException {
User user = new User(1,"杨过","98");
ObjectMapper mapper = new ObjectMapper();
//序列化:obj对象--->json格式
String userToJson = mapper.writeValueAsString(user);
System.out.println(userToJson);
//利用commons-io.jar包实现将上面获取到的经序列化之后得到的json
//格式的string类型的字符串保存到本地的文件中
File file = new File("E:/Java/20200120.txt");
FileUtils.writeStringToFile(file, userToJson, "utf-8");
//将存在与文件中的json格式的字符串转变为对象
//1.将文件中的json格式的字符串读取出来
List<String> list =
FileUtils.readLines(new File("E:/Java/20200120.txt"),"utf-8");
String jsonStr = "";
for (String string : list) {
System.out.println(string);
jsonStr+=string;
}
//2.将读取出来的json格式的数据转变为对象
User jsonToUser = mapper.readValue(jsonStr, User.class);
System.out.println(jsonToUser);
}
}
ps: 将数据序列化为json格式 与 将数据序列化到文件中保存 是拿Maven项目写的
所以相关依赖jar包如下
<!-- https://mvnrepository.com/artifact/
com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/
com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/
com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/
commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.0</version>
</dependency>
6.SerialversionUID关键字的了解
serialVersionUID适用于Java的序列化机制。简单来说,Java的序列化机制
是通过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会
把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进
行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一
致的异常,即是InvalidCastException
简而言之:如果类中有serialVersionUID说明这个类实现了序列化接口,要么是
直接实现要么是间接实现