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

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 对比

TCPUDP
通信双方需要建立并维持连接,占用一定的系统资源通信双方不需要建立连接,占用的系资源少
传输数据可靠,丢包很少发生传输数据不可靠,丢包属于正常现象,丢包时会重传
与 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