[Java] I/O底层原理之二:网络IO及网络编程

首先我们来看一下当访问一个域名时它的过程

  1. 查找 DNS
    1. 首先,浏览器检查缓存中有没有
    2. 浏览器缓存中没有,则查找操作系统中有没有配置这个对应关系
    3. 如果操作系统中也没有,则去 DNS 查找,即发送DNS报文:传输层(UDP数据报)-> 网络层(IP数据包)-> 数据链路层(协议单元)
    4. 如果发送时 ARP 缓存中没有相关数据,则发送 ARP 广播,等待 ARP 回应
    5. ARP 回应后,将 IP 地址与下一跳 MAC 地址写入 ARP 缓存表
    6. 经过多次转发后,数据到达 DNS 服务器,并解析到 IP 地址
  2.  

我们先来看一下 TCP/IP 分层与 OSI 分层的关系

网络层 —— IP(网络之间的互联网协议)、ARP(地址解析协议)、RARP、ICMP

传输层 —— TCP(传输控制协议)、UDP(用户数据报协议)

应用层 —— TeInet(远程登录服务的标准协议)、SMTP(电子邮件协议)、NFS(网络文件服务协议)、SNMP(网络管理协议)、FTP(文本传输协议)、HTTP(超文本传输协议)

本篇博客主要讲述 TCP 协议和 UDP 协议在 Java 中的应用,下面我们来看一下两者的区别:

  • TCP 协议是一种链接可靠的传输协议,通过 TCP 协议传输,得到的是一个顺序无差错的数据流。但是可靠的传输是要付出代价的,对数据的验证会占用计算机处理时间和网络带宽。所以 TCP 传输效率不如 UDP 高。
  • UDP 协议是一种无链接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传送至目的地,但达到目的地的时间及内容的正确性都是不能保证的。在不需要严格保证传输可靠性时,可以使用 UDP 协议,如视频、音频等。

一、Socket与ServerSocket

1 TCP协议

TCP连接的状态转换图如下

 注:SYN 表示建立链接、FIN 表示关闭链接、ACK 表示响应、PSH 表示有数据传输、RST 表示链接重置。

  • CLOSED:初始状态,在超时或连接关闭时也会进入此状态。 
  • LISTEN:服务端在等待连接时的状态。
  • SYN-SENT:客户端发起连接并发送 SYN 给服务端后等待的状态。如果不能连接,则进入 CLOSED 状态。
  • SYN-RCVD:服务端接受客户端的 SYN 请求,由 LISTEN 状态进入此状态。同时回应一个 SYN、ACK 给客户端。
  • ESTABLISHED:数据传输状态,服务端和客户端建立连接后的状态。
  • FIN-WAIT-1:主动关闭的一方进入此状态。等待远程TCP连接中断请求,或先前的连接中断请求的确认
  • FIN-WAIT-2:主动关闭的一方接收另一方的 FIN ACK进入的状态。
  • CLOSE-WAIT:被动关闭的一方收到 FIN 后进入的状态,接收到 FIN 的同时发送 ACK。
  • LAST-ACK:被动关闭的一方发起关闭请求。
  • CLOSING:
  • TIME-WAIT:

1 建立连接的步骤(三次握手)

 

  1. 客户端发送 SYN 给服务端
  2. 服务端回应 ACK 和 SYN  给客户端
  3. 客户端发送 ACK 给服务端

2 断开链接的步骤(四次挥手)

  1. 客户端发送 FIN 给服务端
  2. 服务端回应 ACK
  3. 服务端关闭链接,发送 FIN 给客户端
  4. 客户端回应 ACK 给服务端

 

2 Socket

一个 Socket 实例代表了一个通信链路,当连接建立成功后,服务器和客户端都会各拥有一个 Socket 实例,且这两个实例都会拥有一个 InputStream 和 OutputStream,以此来传输数据。在 InputStream 和 OutputStream 中会各有一个缓存区,数据写入和读取都是通过这个缓存区完成的。通过 OutputStream 将数据写入到其 SendQ 队列中,当队列填满时,数据将被传递到 InputStream 的 RecvQ 队列中,如果这时 RecvQ 已满,则 OutputStream 的 write() 方法将会阻塞,直到 RecvQ 队列有足够空间容纳 SendQ 发送的数据。要注意的是,缓存区的大小及读写宿舍非常影响连接的传输效率,而且由于是阻塞式,如果两遍同时传递数据有可能发生死锁。 

 

posted @ 2017-09-04 00:02  TengYunhao  阅读(528)  评论(0编辑  收藏  举报