1 IO
1.1 java网络编程
1.1.1 基础知识
(1)ip地址和端口号
ip地址:用于识别网络中的一个通讯实体,这个通讯实体可以理解成一台主机,或一台远程打印机,或路由器中的某个端口。 基于IP协议的网络中传输的数据包,必须使用IP地址,寄件人地址+收件人地址,对应表示源IP+目标IP。
一个通讯实体,可以有很多个通讯程序同时对外提供服务,这时需要通过端口号区分这些程序。不能有两个通讯程序使用同一个端口号。即:一个端口号只能对应一个通讯程序。
(2)TCP/UDP协议
tcp协议:是面向连接的,保证可靠传输的协议。通过tcp协议的传输,得到的是一个顺序的无差错的数据流。它能提供两台计算机之间的可靠数据传输。http、ftp这些应用程序,都是基于tcp的可靠传输通信。
udp协议:是无连接协议。每个数据包都是一个独立的信息。包括完整的源地址和目的地址。在网络上可以通过任何途径传输到目的地。置于能否达到目的地,达到目的地的时间和准确性是不能保证的。
有了可靠的tcp,为何还需不可靠的udp?
原因:可靠是要有代价的,对内容到达时间和内容本身的检验必然会占用计算机处理时间和网络带宽,因此传输效率,tcp肯定不如udp高。再者,很多应用程序并不需要保证严格的传输可靠性,如视频聊天,无需视频和音频绝对正确,只要保证连贯性就可以了,这时用udp更合适。
(3)URL
统一的资源定位器,指向互联网中的任何一个资源。
从输入流中读取数据,再通过输出流写入文件。输出的结果就是:输入的浏览器的地址给我们服务器返回的内容。
(4)InetAddress
java提供的代表IP地址的一个类。
1.1.2 socket
(1)创建socket实例
主机A的应用程序要和主机B的应用程序通信,必须通过socket建立连接。
而要建立socket连接就必须得底层的TCP/IP协议建立TCP连接。
建立TCP连接的过程,需要底层的TCP协议去寻找网络中的主机。
网络层使用的IP协议,可以帮助我们根据IP地址来找到目标主机。
但是一台主机上可能运行着多个程序,如何与指定的程序通信,就得通过TCP或UDP的地址,即端口号,来指定。
这样,就可以通过一个socket实例,代表一个主机上的应用程序,来进行通信连接了。
(2)客户端的链接
(3)服务端的链接
(4)总结
1.2 阻塞IO(BIO)
1.2.1 java的I/O接口
基于字节操作的 I/O 接口:InputStream 和 OutputStream
基于字符操作的 I/O 接口:Writer 和 Reader
基于磁盘操作的 I/O 接口:File和RandomAccessFile
基于网络操作的 I/O 接口:Socket
前两组主要是根据传输数据的数据格式,后两组主要是根据传输数据的方式。另Socket不在java.io下而在java.net下,但由于也在这地方设计I/O的操作,所以也于此归类。
1.2.2 阻塞IO的通信模型
调用accept方法后,服务端阻塞等待客户端连接。
当有客户端连接时,服务端创建一个线程用于处理这个客户端的连接。
缺点1:当客户端很多的时候,服务端会创建大量的处理线程,每个线程都会占用栈空间和CPU的时间。
缺点2:阻塞可能带来频繁的上下文切换。而它的大部分的上下文切换都是无意义的,加重了CPU的负担。
总结
1.3 NIO
1.3.1 NIO工作原理
有一个专门的线程,处理所有的IO事件。
是事件驱动机制的,当事件到来的时候会触发,而非同步地监视事件。
有线程间的通信方式。线程之间通过wait和notify方式通信的。保证每次上下文切换都是有意义的,减少cpu负担。
1.3.2 NIO通信模型
NIO服务端只需要专门的线程,处理所有的IO事件。
NIO采用双向通道进行数据传输,而不是像传统的阻塞式IO使用单向的流。
在通道上,我们可以注册我们感兴趣的事件,如:服务端会接受客户端连接事件、客户端连接服务端事件、读事件、写事件,共4大事件。
服务端和客户端,各自维护了一个管理通道的对象selector。它能检测到一个或多个channel,channel上的事件都能被selector检测到。