Java网络编程

I/O流

I/O:Input/Output,用于处理设备间的数据传输。如文件读写,网络通讯等。

流的分类

  • 数据单位区分:字节流(8 bit,一般用于文件)字符流(16 bit,一般用于文本)

  • 流向区分:输入流,输出流

  • 流的角色区分:节点流^1arrow-up-right,处理流^2arrow-up-right

I/O流体系

分类
字节输入流
字节输出流
字符输入流
字符输出流

抽象基类

InputStream

OutputStream

Reader

Writer

FileInputStream

FileOutputStream

FileReader

FileWriter

BufferedInputStream

BufferedOutputStream

BufferedRTeader

BufferedWriter

转换流

InputStreamReader

OutputStreamWriter

对象流

ObjectInputStream

ObjectOutputStream

字符流

用于文本文件(.txt,.hava,.c,.cpp等)

FileReader

读取hello.txt文件

其他read()的重载方法

FileWriter

写出数据到硬盘文件

字节流

对于非文本文件(.jpg,.mp3,.doc等),用字节流处理。

FileInputStream & FileOutputStream

使用字节流复制图片

缓冲流

BufferedInputStream BufferedOutputStream BufferedRTeader BufferedWriter

相较于节点流的读取,写入有速度提升。

**注:**利用I/O流复制文件时可以通过利用以下方式异或加密/解密文件;

c = a ^ b ; #其中^为异或符号

a = c ^ b ;

其他运算符 >> 、<< 、>>> 、<<< 即位运算,对某数的二进制**补码^5arrow-up-right**进行位运算。

其中<< 低位补0 ;

其中>>为正数时高位补0,负数时高位补1;

而>>>、<<<则缺位都补0

转换流

提供字节流与字符流之间的转换。属于字符流。

  • InputStreamReader:将一个字节的输入流转换为字符的输入流;

  • OutputStreamWriter:将一个字符的输出流转换成字节的输出流;

注: ASCALL码数字 ‘ 0 ’ = 48;' A ' = 65;' a ' = 97

标准流

详见常见算法题2

对象流

ObjectoutputStreamObjectInputStream用于存储和读取基本数据类型数据或对象类型数据的处理。可以将Java中的对象写入到数据源中,也可以把对象从数据源中还原回来。

  • 序列化:用ObjectoutputStream类保存基本数据类型或对象的过程。

  • 反序列化:用ObjectInputStream类读取基本数据类型或对象的过程。

注:ObjectoutputStreamObjectInputStream都不能序列化static和`transient^6arrow-up-right修饰的成员变量。

对象序列化机制允许把内存中的Java对象转换成与平台无关的二进制流,从而允许将其保存到磁盘或进行网络传输。当其他程序获取这种二进制流,就可以恢复成原来的Java对象。

任何实现了Serializable接口的对象都可以被转换成字节数据,在保存和传输时可被还原。

  • Serializable接口为标识接口,其中没有任何方法需要实现。

  • 实现Serializable接口必须提供一个staticfinal标识且名为的serialVersionUIDlong型属性以识别不同的类。

  • 如果没有显示提供serialVersionUIDJava会自动生成一个值。但如果对类序列化之后修改类,则在反序列化过程中会报InvalidClassException的异常。

  • 需要序列化的类其所有属性都需要实现序列化接口。(默认情况下,基本属性类型可序列化)

常见算法题

统计某字符串或文本上每个字符出现的次数。

读取控制台输入的整行字符串并转换成大写输出。



网络编程

Java提供了对网络应用程序的支持。其提供的网络类库可以实现无痛 的网络连接,底层的细节由JVM控制。并且Java实现了要给跨平台的网络库。

网络编程目的:直接或简介的通过网络协议与其他计算机通讯,实现数据交换。

通讯要素

IP和端口号

Java中使用InetAddress类封装IP。常用方法如下:

端口号标识正在计算机上运行的进程(程序)。

  • 不同进程有不同的端口号

  • 被稳定为一个16位的整数0~65535

  • 端口分类:

    • 公认端口:0~1023.预先被定义的服务通信占用。

    • 注册端口:1024~49151:分配给用户进程或应用程序。

    • 动态/私有端口:49152~65535.

端口号和IP地址组合得到网络套接字:Socket

网络协议

计算机网络中实现通信的一些约定。

TCP协议

TCP协议报文格式

img

通过“三次握手”建立点对点,可靠连接,形成传输数据通道。

img

传输完毕通过”四次挥手“释放以建立的连接。

img

UDP协议

  • 不需要建立连接,不需要确认,不可靠。

  • 数据报大小限制再64K。

TCP网络编程

单元测试模拟客户端和服务器通信。客户端上传图片给服务器,服务器接收后返回确认信息并关闭连接。Java1.7之后多用NIO实现

UDP网络编程

单元测试模拟接收,发送数据。

URL类

URL(Uniform Resource Locator):统一资源定位符,表示Internet上某一资源的地址。

格式:

http://192.168.100:8080/helloworld/index.html?username=Tom

协议 地址 端口号 资源地址 参数列表

NIO

Java 1.4之后开始引入的一套新的IO API,与原来的IO作用和目的相同,但使用方式不同。可以替代标准的Java IO API。

IO是面向流的。NIO支持面向缓冲区、基于通道的IO操作。

相较于传统IO。NIO是非阻塞式的。

Java NIO核心在于通道(Channel)和缓冲区(Buffer)。通道表示打开对IO设备(文件、套接字等)的连接。然后操作缓冲区,对数据进行处理。即Channel负责传输,Buffer负责存储

缓冲区(Buffer)

缓冲区(Buffer):在Java NIO中负责数据的存取。

  • 底层实现是数组。

  • boolean类型外,所有基本数据类型都有对应的缓冲区。

直接缓冲区:通过allocatedDirect()方法分配,将缓冲区建立再物理内存中。

非直接缓冲区:通过allocated()方法分配,建立再JVM内存中。

常用方法:

通道(Channel)

通道(Channel):由java.nio.channels包定义的,表示IO源与目标打开的连接。

  • 通道不能直接访问数据,只能与Buffer进行交互。

  • 主要实现类:

获取Channel的方式

  1. 对应流的getChannel()方法获得对应的Channel

  1. 各通道实现类的静态方法open()获得

  1. Files工具类的newByteChannel()方法

Channel传输数据的方式

  1. 通过Buffer传输

  1. 通过Channel的transferFrom()transferTo()方法

**注:**其channel底层实现也是通过方式一。

  1. 通过直接缓冲区传输

字符集(Charset)

  • 编码Encoder: 字符串 -> 字节数组

  • 解码Decider: 字节数组 -> 字符串

NIO实现网络通信(阻塞式)

单元测试模拟通过NIO实现网络通信,与TCP网络编程基本类似

NIO实现网络通信(非阻塞式)

Selector(选择器)

利用Selector(选择器)检查一个或多个NIO Channel(通道)的状态。如此可以实现单线程管理多个Channels,以管理多个网络链接。

以上连接是基于TCP的,对与UDP的连接来说,只需通过DatagramChannel.open()方法即可获取到对应的DatagramChannal通道。并且作为单向传输的协议,发送端不要设置端口号,只需要指定接收端的地址和端口号即可。

管道(Pipe)

Java NIO管道是两个线程之间的单向数据连接。通过Pipe有一个提供写入数据的Sink通道和一个提供数据读取的Source通道。


最后更新于