网络编程(一)网络编程基础

OSI 七层模型

层数 名称 作用
7 应用层 网络服务与最终用户的一个接口
6 表示层 把应用层提供的信息变换为能够共同理解的形式
5 会话层 建立、管理、终止会话。
4 传输层 定义传输数据的协议端口号,以及流控和差错校验
3 网络层 路由选择和中继,在一条数据链路上复用多条网络连接
2 数据链路层 数据链路的建立,拆除,对数据的检错,纠错是数据链路层的基本任务。
1 物理层 物理层并不是物理媒体本身,它只是开放系统中利用物理媒体实现物理连接的功能,描述和执行连接的程序

TCP/IP 协议

OSI 七层模型 TCP/IP 概念层模型 功能 TCP/IP 协议族
应用层 应用层 文件传输,电子邮件,文件服务,虚拟终端 tftp、http、snmp、ftp、smtp、dns、telnet
表示层 应用层 数据格式化,代码转换,数据加密 没有协议
会话层 应用层 解除或建立与别的节点的联系 没有协议
传输层 传输层 提供端对端的接口 tcp、udp
网络层 网络层 为数据包选择路由 ip、icmp、rip、ospf、bcp、icmp
数据链路层 链路层 传输有地址的帧以及错误检测功能 slip、cslip、ppp、arp、rarp、mtu
物理层 链路层 以二进制数据形式在物理媒体上传输数据 iso2110、ieee802、ieee802.2

20170129235309180.jpg

数据传输过程

IP 包结构是这样的:
1.jpg
TCP 的包结构:
2.jpg
基于 TCP 和 UDP 的数据封装及解析示例如下:
3.jpg

TCP 和 UDP

TCP

TCP 是面向连接的、可靠的流协议,通过三次握手建立连接,通讯完成时要拆除连接。

三次握手

6.png

  • B 的 TCP 服务器进程先创建传输控制块 TCB,准备接受客户进程的连接请求。然后服务器进程就处于 LISTEN(收听)状态,等待客户的连接请求。若有,则作出响应。
  • 1)第一次握手:A 的 TCP 客户进程也是首先创建传输控制块 TCB,然后向 B 发出连接请求报文段,(首部的同步位 SYN=1**,初始序号 seq=x),(SYN=1 的报文段不能携带数据)但要消耗掉一个序号,此时 TCP 客户进程进入 SYN-SENT(同步已发送)状态。
  • 2)第二次握手:**B 收到连接请求报文段后,如同意建立连接,则向 A 发送确认,在确认报文段中(SYN=1,ACK=1,确认号 ack=x+1,初始序号 seq=y),测试 TCP 服务器进程进入 SYN-RCVD(同步收到)状态;
  • 3)第三次握手:**TCP 客户进程收到 B 的确认后,要向 B 给出确认报文段(ACK=1,确认号 ack=y+1,序号 seq=x+1)(初始为 seq=x,第二个报文段所以要 +1),ACK 报文段可以携带数据,不携带数据则不消耗序号。TCP 连接已经建立,A 进入 ESTABLISHED(已建立连接)。
  • 当 B 收到 A 的确认后,也进入 ESTABLISHED 状态。

总结三次握手过程:

  • 第一次握手:起初两端都处于 CLOSED 关闭状态,Client 将标志位 SYN 置为 1,随机产生一个值 seq=x,并将该数据包发送给 Server,Client 进入 SYN-SENT 状态,等待 Server 确认;
  • 第二次握手:Server 收到数据包后由标志位 SYN=1 得知 Client 请求建立连接,Server 将标志位 SYN 和 ACK 都置为 1,ack=x+1,随机产生一个值 seq=y,并将该数据包发送给 Client 以确认连接请求,Server 进入 SYN-RCVD 状态,此时操作系统为该 TCP 连接分配 TCP 缓存和变量;
  • 第三次握手:Client 收到确认后,检查 ack 是否为 x+1,ACK 是否为 1,如果正确则将标志位 ACK 置为 1,ack=y+1,并且此时操作系统为该 TCP 连接分配 TCP 缓存和变量,并将该数据包发送给 Server,Server 检查 ack 是否为 y+1,ACK 是否为 1,如果正确则连接建立成功,Client 和 Server 进入 ESTABLISHED 状态,完成三次握手,随后 Client 和 Server 就可以开始传输数据。
四次挥手

7.png

  • 1)A 的应用进程先向其 TCP 发出连接释放报文段(FIN=1,序号 seq=u),并停止再发送数据,主动关闭 TCP 连接,进入 FIN-WAIT-1(终止等待 1)状态,等待 B 的确认。
  • 2)B 收到连接释放报文段后即发出确认报文段,(ACK=1,确认号 ack=u+1,序号 seq=v),B 进入 CLOSE-WAIT(关闭等待)状态,此时的 TCP 处于半关闭状态,A 到 B 的连接释放。
  • 3)A 收到 B 的确认后,进入 FIN-WAIT-2(终止等待 2)状态,等待 B 发出的连接释放报文段。
  • 4)B 没有要向 A 发出的数据,B 发出连接释放报文段(**FIN=1,ACK=1,序号 seq=w,确认号 ack=u+1),**B 进入 LAST-ACK(最后确认)状态,等待 A 的确认。
  • 5)A 收到 B 的连接释放报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),A 进入 TIME-WAIT(时间等待)状态。此时 TCP 未释放掉,需要经过时间等待计时器设置的时间 2MSL 后,A 才进入 CLOSED 状态。

总结四次挥手过程:

起初 A 和 B 处于ESTABLISHED 状态——A 发出连接释放报文段并处于FIN-WAIT-1 状态——B 发出确认报文段且进入CLOSE-WAIT 状态——A 收到确认后,进入FIN-WAIT-2 状态,等待 B 的连接释放报文段——B 没有要向 A 发出的数据,B 发出连接释放报文段且进入LAST-ACK 状态——A 发出确认报文段且进入TIME-WAIT 状态——B 收到确认报文段后进入CLOSED 状态——A 经过等待计时器时间 2MSL 后,进入CLOSED 状态

UDP

UDP 是面向无连接的通讯协议,UDP 通讯时不需要接收方确认,属于不可靠的传输,可能会出现丢包现象。

TCP 与 UDP 对比

TCP UDP
通信双方需要建立并维持连接,占用一定的系统资源 通信双方不需要建立连接,占用的系资源少
传输数据可靠,丢包很少发生 传输数据不可靠,丢包属于正常现象,丢包时会重传
与 TCP 相比,传输效率高,通讯速度快
对传输质量要求较高时使用 TCP 协议 对传输质量要求不高,要求传输速度更快时使用 UDP 协议

端口号

端口号用来识别同一台计算机中进行通信的不同应用程序,因此,它也被称为程序地址。

Socket

Socket 是应用层与 TCP/IP 协议族通信的中间软件抽象层,它是一组接口。
4.jpg

JAVA 中实现通信的 IO 主要是:同步阻塞 IO(BIO)、同步非阻塞 IO(NIO)、异步非阻塞 IO(AIO)。

同步和异步,阻塞和非阻塞

同步和异步关注结果是否立即返回;
阻塞和非阻塞关注调用方是否等待结果返回。

linux 下的五种 I/O 模型

(1) 阻塞 I/O (Blocking I/O)
1.png

从上图可以看到在整个过程中,当用户进程进行系统调用时,内核就开始了 I/O 的第一个阶段,准备数据到缓冲区中,当数据都准备完成后,则将数据从内核缓冲区中拷贝到用户进程的内存中,这时用户进程才解除 block 的状态重新运行。
所以,Blocking I/O 的特点就是在 I/O 执行的两个阶段都被 block 了。
(2) 非阻塞 I/O (Non-Blocking I/O)
2.png

从上图可以看到在 I/O 执行的两个阶段中,用户进程只有在第二个阶段被阻塞了,而第一个阶段没有阻塞,但是在第一个阶段中,用户进程需要盲等,不停的去轮询内核,看数据是否准备好了,因此该模型是比较消耗 CPU 的。
(3) I/O 复用(I/O Multiplexing)
3.png

从上图可以看到在 I/O 复用模型中,I/O 执行的两个阶段都是用户进程都是阻塞的,但是两个阶段是独立的,在一次完整的 I/O 操作中,该用户进程是发起了两次系统调用。
(4) 信号驱动的 I/O (Signal Driven I/O)
4.png

该模型也叫作基于事件驱动的 I/O 模型,可以看到该模型中,只有在 I/O 执行的第二阶段阻塞了用户进程,而在第一阶段是没有阻塞的。
乍看起来感觉和非阻塞模型很相似,其实不同之处就在于,该模型在 I/O 执行的第一阶段,当数据准备完成之后,会主动的通知用户进程数据已经准备完成,即对用户进程做一个回调。该通知分为两种,一为水平触发,即如果用户进程不响应则会一直发送通知,二为边缘触发,即只通知一次。
(5) 异步 I/O (Asynchrnous I/O)
5.png

在该模型中,当用户进程发起系统调用后,立刻就可以开始去做其它的事情,然后直到 I/O 执行的两个阶段都完成之后,内核会给用户进程发送通知,告诉用户进程操作已经完成了。

unix 网络编程

下一篇 网络编程(二)BIO