Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。
将序列化对象写入文件之后,可以从文件中读取出来,并且对它进行反序列化,也就是说,对象的类型信息、对象的数据,还有对象中的数据类型可以用来在内存中新建对象。
整个过程都是 Java 虚拟机(JVM)独立的,也就是说,在一个平台上序列化的对象可以在另一个完全不同的平台上反序列化该对象。
类 ObjectInputStream 和 ObjectOutputStream 是高层次的数据流,它们包含反序列化和序列化对象的方法。
ObjectOutputStream 类包含很多写方法来写各种数据类型,但是一个特别的方法例外:
public final void writeObject(Object x) throws IOException
上面的方法序列化一个对象,并将它发送到输出流。相似的 ObjectInputStream 类包含如下反序列化一个对象的方法:
public final Object readObject() throws IOException, ClassNotFoundException
该方法从流中取出下一个对象,并将对象反序列化。它的返回值为Object,因此,你需要将它转换成合适的数据类型。
序列化对象
package com.zhouzy.base.t9; import java.io.Serializable; /** * 实现序列化接口,Serializable * @author Administrator * */ public class UserInfo implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private String name; private String sex; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
读写序列化对象-文件操作
package com.zhouzy.base.t9; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import org.junit.Test; public class SerializeTest { @Test public void serializeTest(){ //先定义序列化的对象 UserInfo user = new UserInfo(); user.setName("张三"); user.setAge(23); user.setSex("男"); //写入文件 try { FileOutputStream fileOut = new FileOutputStream("E://test.txt"); ObjectOutputStream oos = new ObjectOutputStream(fileOut); oos.writeObject(user); //写入序列化对象 fileOut.close(); oos.close(); } catch (Exception e) { e.printStackTrace(); } //文件读出序列化对象 try { FileInputStream filein = new FileInputStream("E://test.txt"); ObjectInputStream ois = new ObjectInputStream(filein); UserInfo userObject = (UserInfo)ois.readObject(); //写入序列化对象 filein.close(); ois.close(); System.out.println("name:"+userObject.getName()); System.out.println("age:"+userObject.getAge()); System.out.println("sex:"+userObject.getSex()); } catch (Exception e) { e.printStackTrace(); } } }
结果:
name:张三
age:23
sex:男
网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。
java.net 包中 J2SE 的 API 包含有类和接口,它们提供低层次的通信细节。你可以直接使用这些类和接口,来专注于解决问题,而不用关注通信细节。
java.net 包中提供了两种常见的网络协议的支持:
TCP:TCP(英语:Transmission Control Protocol,传输控制协议) 是一种面向连接的、可靠的、基于字节流的传输层通信协议,TCP 层是位于 IP 层之上,应用层之下的中间层。TCP 保障了两个应用程序之间的可靠通信。通常用于互联网协议,被称 TCP / IP。
UDP:UDP (英语:User Datagram Protocol,用户数据报协议),位于 OSI 模型的传输层。一个无连接的协议。提供了应用程序之间要发送数据的数据报。由于UDP缺乏可靠性且属于无连接协议,所以应用程序通常必须容许一些丢失、错误或重复的数据包。
本教程主要讲解以下两个主题。
Socket 编程:这是使用最广泛的网络概念,它已被解释地非常详细。
URL 处理:这部分会在另外的篇幅里讲,点击这里更详细地了解在 Java 语言中的 URL 处理。
ServerSocket 类有四个构造方法:
序号 | 方法描述 |
1 | public ServerSocket(int port) throws IOException 创建绑定到特定端口的服务器套接字。 |
2 | public ServerSocket(int port, int backlog) throws IOException 利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。 |
3 | public ServerSocket(int port, int backlog, InetAddress address) throws IOException 使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器。 |
4 | public ServerSocket() throws IOException 创建非绑定服务器套接字。 |
这里有一些 ServerSocket 类的常用方法:
序号 | 方法描述 |
1 | public int getLocalPort() 返回此套接字在其上侦听的端口。 |
2 | public Socket accept() throws IOException 侦听并接受到此套接字的连接。 |
3 | public void setSoTimeout(int timeout) 通过指定超时值启用/禁用 SO_TIMEOUT,以毫秒为单位。 |
4 | public void bind(SocketAddress host, int backlog) 将 ServerSocket 绑定到特定地址(IP 地址和端口号)。 |
Socket 类有五个构造方法.
序号 | 方法描述 |
1 | public Socket(String host, int port) throws UnknownHostException, IOException. 创建一个流套接字并将其连接到指定主机上的指定端口号。 |
2 | public Socket(InetAddress host, int port) throws IOException 创建一个流套接字并将其连接到指定 IP 地址的指定端口号。 |
3 | public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException. 创建一个套接字并将其连接到指定远程主机上的指定远程端口。 |
4 | public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException. 创建一个套接字并将其连接到指定远程地址上的指定远程端口。 |
5 | public Socket() 通过系统默认类型的 SocketImpl 创建未连接套接字 |
socket方法:
号 | 方法描述 |
1 | public void connect(SocketAddress host, int timeout) throws IOException 将此套接字连接到服务器,并指定一个超时值。 |
2 | public InetAddress getInetAddress() 返回套接字连接的地址。 |
3 | public int getPort() 返回此套接字连接到的远程端口。 |
4 | public int getLocalPort() 返回此套接字绑定到的本地端口。 |
5 | public SocketAddress getRemoteSocketAddress() 返回此套接字连接的端点的地址,如果未连接则返回 null。 |
6 | public InputStream getInputStream() throws IOException 返回此套接字的输入流。 |
7 | public OutputStream getOutputStream() throws IOException 返回此套接字的输出流。 |
8 | public void close() throws IOException 关闭此套接字。 |
序号 | 方法描述 |
1 | static InetAddress getByAddress(byte[] addr) 在给定原始 IP 地址的情况下,返回 InetAddress 对象。 |
2 | static InetAddress getByAddress(String host, byte[] addr) 根据提供的主机名和 IP 地址创建 InetAddress。 |
3 | static InetAddress getByName(String host) 在给定主机名的情况下确定主机的 IP 地址。 |
4 | String getHostAddress() 返回 IP 地址字符串(以文本表现形式)。 |
5 | String getHostName() 获取此 IP 地址的主机名。 |
6 | static InetAddress getLocalHost() 返回本地主机。 |
7 | String toString() 将此 IP 地址转换为 String。 |
package com.zhouzy.base.t9; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; /** * socket服务端 * @author Administrator * */ public class Server extends Thread{ @SuppressWarnings("resource") public void run() { try { ServerSocket server = new ServerSocket(8088); server.setSoTimeout(50000); while(true){ Socket socket = server.accept(); System.out.println("当前连进来的地址为:" + socket.getRemoteSocketAddress()); DataInputStream in = new DataInputStream(socket.getInputStream()); System.out.println("客户端发送的信息为:"+in.readUTF()); DataOutputStream out = new DataOutputStream(socket.getOutputStream()); out.writeUTF("hello,我是服务端"); socket.close(); } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { Thread t = new Server(); t.start(); } }
package com.zhouzy.base.t9; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; /** * socket服务端 * @author Administrator * */ public class Client extends Thread{ public void run(){ try { Socket client = new Socket("127.0.0.1",8088); System.out.println("当前连服务器的地址为:" + client.getRemoteSocketAddress()); OutputStream outToServer = client.getOutputStream(); DataOutputStream out = new DataOutputStream(outToServer); out.writeUTF("hello,我是客户端"); InputStream inFromServer = client.getInputStream(); DataInputStream in = new DataInputStream(inFromServer); System.out.println("客户端受到的信息为:"+in.readUTF()); client.close(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { Thread t = new Client(); t.start(); } }
结果:
服务端日志:
客户端日志:
这个例子是简单的网络编程,想要了解更多,点击下面链接:
TCP/UDP网络编程:https://blog.csdn.net/wwwzhouzy/article/details/118058048
NIO编程:https://blog.csdn.net/wwwzhouzy/article/details/118058069
Netty编程:https://blog.csdn.net/wwwzhouzy/article/details/118058098
Netty解决拆包粘包的三种方案:https://blog.csdn.net/wwwzhouzy/article/details/119154039