第一章:简介:
这一章的内容是一些基础知识的概述:
- 计算机网络的概念,分组报文和协议
- 以太网
- HTTP
- TCP/IP协议族(UDP)
- OSI七层网络结构
- 地址的概念 IPv4(32bit)、IPv6(128bit)
- DNS的相关概念,地址解析协议
- C/S模式 客户端和 服务器端
- 套接字的概念(IP地址+PORT端口)
- 流套接字(stream socket)TCP协议
- 数据报套接字(datagram socket)UDP协议
第二章:基本套接字
这一章主要介绍了最基本的socket编程,采用最初的阻塞方式。主要有几个Java类的使用要注意。
- InetAddress网络地址类
- 获取InetAddress类实例的方法:
- getAllByName(String host) 静态工厂方法获取网络地址类
- getByName()
- getLocalHost()
- getAddress()
- 检测类属性的相关方法
- isAnyLocalAddress()
- isMCGlobal()
- isReadable()
- 等等
- 获取InetAddress类实例的方法:
- NetWorkInterface类
- TCP套接字
- Socket 客户端创建
- ServerSocket 服务器端创建
- OutputStream 输出流,利用其向对方发送数据
- InputStream 输入流,读取对方放过来得数据
- UDP套接字
- DatagramPacket类,表示数据报。
- DatagramSocket类,用来发送DatagramPacket的实例
TCP套接字的创建流程
客户端:
1. 创建一个Socket实例:构造函数指向的远程主机和端口建立一个TCP连接。
2. 通过套接字的输入输出流(I/O streams)进行通信:一个Socket连接实例包括一个InputStream和OutputStream。
3. 使用Socket类的close()方法关闭连接。
服务器端:
- 创建一个ServerSocket实例并指定本地端口。
- 重复执行:
- 调用ServerSocket的accept()方法以获取下一个客户端连接。基于新建立的客户端连接,创建一个Socket实例,并由accept()方法返回。
- 使用返回的Socket实例的InputStream和OutputStream与客户端进行通信。
- 通信完成后,使用Socket类的close()方法关闭该客户端套接字连接。
第三章:发送和接收数据:
这一章主要讲述了应用程序编码,因为最初的输入输出流只能传输字节码,像short、int、long等等这些数据类型是传输不了的,所以我们要想办法。
- 大端模式和小端模式
- 组合输入输出流
- 成帧与解析(如何定位消息的首尾位置)
- 基于定界符
- 显式长度
- 构建和解析协议消息
- 基于文本的表示方法(使用ASC码字符集对文本进行编码)
- 二进制表示方法(自己编码010101代表一个值)
第四章:进阶
这一章主要讲述了多线程技术来处理多个客户端请求,并引入了线程池的概念,后面也介绍了UDP广播和多播的内容。
- Java多线程
- 线程池的使用
- Executor接口
- 阻塞和超时
- 限制读写的时间
- 多接受者
- 广播
- 多播
- 控制默认行为
- keep-alive机制
- 发送噩耗接收缓存区的大小
- 超时的参数设定
- 地址重用
- 消除缓存延迟
- 紧急数据(虽然没什么用)
- 关闭后停留
- 广播许可
- 通信等级
- 基于性能的协议选择
- 关闭连接(多种方法)
- close()
- shutdownOutput
- shutdownInput
第五章:NIO
- buffer 缓冲区,底层为后援存储空间,与channel进行通信。
- 索引访问:
- capacity 缓冲区中元素总数
- position 下一个要读的元素(从0开始)
- limit 第一个不可读的元素
- mark 用户选定的position的前一个位置
- 存储和接受数据的方法:
- get() -会抛出BufferUnderflowException异常
- put() -会抛出IndexOutOfBoundsException异常
- 多字节数据在字节数组中的存储方式:Java默认大端模式
- BIG_ENDING
- LITTLE_ENDING
- 部分函数:调整position、limit的值
- clear()
- flip()
- rewind() 通常用在日志的写入
- buffer压缩
- compact()用于节省缓冲区的空间
- buffer透视
- duplicate()
- slice()
- 字节编码
- 索引访问:
- channel 信道, 类似于 socket。
- channel种类,有两个变体:
- SocketChannel 相当于客户端
- ServerSocketChannel 相当于服务器端
- 信道的创建、连接和关闭
- open()
- connect()
- isConnect()
- close()
- isOpen()
- socket() 对包含的Socket进行访问
- SocketChannel的读和写
- read() 包含多种参数的重载方法
- write() 包含多种参数的重载方法
- channel种类,有两个变体:
- Selecttor 管理检查多个信道的I/O。
- selector需要在信道(channel)上注册,selector跟channel之间的关联由一个SelectorKey实例表示。
- SelectorKey类中的常量定义了信道上感兴趣的操作类型,存放在bitmap(位图)中。
- 相关方法:
- select()
- wakeup()
- selectNow()
- keys()返回所有已注册的键
- selectedKeys() 上次调用被选中,并已准备好进行I/O操作的键
最后来一个Selector的小结:
Selector的使用步骤
- 创建一个Selector实例。
- 将其注册到各种信道,指定每一个信道上感兴趣的I/O操作。
- 重复执行:
- 调用一种select方法
- 获取选取的键列表
- 对于已选键集中的每一个键
- 获取信道,并从键中获取附件
- 确定准备就绪的操作并执行。如果是accept操作,将接受的信道设置为非阻塞模式,并将其与选择器注册。
- 如果需要,修改键的兴趣操作集。
- 从已选键中移除键。
第六章:深入剖析
对socket和serversocket实例的底层细节进行的介绍。
- 不能假设在链接一端将数据写入输出流和另一端从输入流读出数据之间有任何一致性。
- TCP连接上会被分成3个FIFO队列
- SendQ
- RecvQ
- Delivered
- 死锁风险
- TCP套接字的生存周期
- 三次握手创建连接
- 四次挥手关闭连接