socket通信之一:TCP/IP模型与socket

这段时间看了一些网络相关的东西,这里做一个总结吧。参考了很多文章的内容,因为我本身是对着书并且参考网络资源在学习的,在最后会一一列出文章的地址。


这篇文章主要介绍TCP/IP的一些基本知识,后面几篇继续深入一点探究。

本篇主要包括下面这些知识:

  1. TCP/IP是什么
  2. socket介绍
  3. socket通信流程
  4. socket中TCP三次握手建立连接
  5. socket中TCP的四次挥手释放连接


1.TCP/IP是什么


首先看一个引出TCP/IP协议族的问题,网络之间的进程如何进行通信?


在本地可以通过进程PID来唯一标识一个进程,但是在网络中这是行不通的。TCP/IP协议族帮我们解决了这个问题,网络层的“ip地址”可以唯一标识网络中的主机,而传输层的“协议+端口”可以唯一标识主机中的应用程序(进程)。这样利用三元组(ip地址,协议,端口)就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互。


上面的例子告诉我们TCP/IP是用来干什么的,即它是用来让网络之间的进程通信时使用的。那么什么是TCP/IP?TCP/IPTransmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。它定义了主机如何连入因特网及数据如何它们之间传输的标准。


从字面意思来看TCP/IP是TCP和IP协议的合称,但实际上TCP/IP协议是指因特网整个TCP/IP协议族。不同于ISO模型的七个分层,TCP/IP协议参考模型把所有的TCP/IP系列协议归类到四个抽象层中

应用层:TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 等等
运输层:TCP,UDP
网络层:IP,ICMP,IGMP
数据链路层:SLIP,CSLIP,PPP,MTU

每一抽象层建立在低一层提供的服务上,并且为高一层提供服务,看起来大概是这样子的。

图1



IOS参考模型和TCP/IP模型的对比:

图2


看完上面的图表,对TCP/IP协议族应该有了一个大概的了解,它是指涉及到通讯过程中的一系列的协议,包括网络接口处,网络层,传输层的协议。为什么要将网络通讯划分成这么多层次呢?因为它比较复杂,如果只用一个层来实现整个通讯流程,那么这个层次会非常复杂,既不利于维护,也不利于扩展。从软件工程的角度来考虑这个问题就很好理解了。不得不说最开始设计TCP/IP的人真是天才啊,知道要分层很容易想到,但是如何分层又是一个大问题,最早的那批先辈们帮我们解决了这个问题。我们现在只需要学习各个分层的作用就可以了。


2.socket介绍


看完上面的图1中TCP/IP的介绍,但是都没有socket的影子,那么它在哪儿呢?

图3

首先必须明确socket不是某一层的协议,它是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组编程接口(即API),在设计模式中,socket就是门面模式(又称为外观模式,Facade),它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让socket去组织数据,以符合指定的协议。


socket起源于UNIX,在Unix一切皆文件哲学的思想下,socket是一种"打开—读/写—关闭"模式的实现,服务器和客户端各自维护一个"文件",在建立连接打开后,可以向自己文件写入内容供对方读取或者读取对方内容,通讯结束时关闭文件。


3.socket通信流程


socket是"打开—读/写—关闭"模式的实现,以使用TCP协议通讯的socket为例,其交互流程大概是这样子的




上面是文字描述,对应于socket api中的函数如下图:




也就是说客户端和服务端的流程是这样子的:

客户端的流程如下:

  1. 创建套接字(socket)
  2. 向服务器发出连接请求(connect)
  3. 和服务器端进行通信(send/recv)
  4. 关闭套接字


服务器端的流程如下:

  1. 创建套接字(socket)
  2. 将套接字绑定到一个本地地址和端口上(bind)
  3. 将套接字设为监听模式,准备接收客户端请求(listen)
  4. 等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)
  5. 用返回的套接字和客户端进行通信(send/recv)
  6. 返回,等待另一个客户请求。
  7. 关闭套接字。


上面就是编写socket程序时客户端和服务器端的基本步骤,每一个socket程序的基本步骤都是上面那几步。


4.socket中TCP三次握手建立连接


在TCP/IP协议中,TCP协议通过三次握手建立一个可靠的连接。



  1. 第一次握手:客户端尝试连接服务器,向服务器发送syn包(同步序列编号Synchronize Sequence Numbers),syn=j,客户端进入SYN_SEND状态等待服务器确认
  2. 第二次握手:服务器接收客户端syn包并确认(ack=j+1),同时向客户端发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态
  3. 第三次握手:第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手


服务器socket与客户端socket建立连接的部分其实就是大名鼎鼎的三次握手。




从图中可以看出,当客户端调用connect时,触发了连接请求,向服务器发送了SYN J包,这时connect进入阻塞状态;服务器监听到连接请求,即收到SYN J包,调用accept函数接收请求向客户端发送SYN K ,ACK J+1,这时accept进入阻塞状态;客户端收到服务器的SYN K ,ACK J+1之后,这时connect返回,并对SYN K进行确认;服务器收到ACK K+1时,accept返回,至此三次握手完毕,连接建立。


故客户端的connect在三次握手的第二个次返回,而服务器端的accept在三次握手的第三次返回。


5.socket中TCP的四次挥手释放连接


上面介绍了socket中TCP的三次握手建立过程,及其涉及的socket函数。现在我们介绍socket中的四次握手释放连接的过程,请看下图:


图示过程如下:

  1. 某个应用进程首先调用close主动关闭连接,这时TCP发送一个FIN M;
  2. 另一端接收到FIN M之后,执行被动关闭,对这个FIN进行确认。它的接收也作为文件结束符传递给应用进程,因为FIN的接收意味着应用进程在相应的连接上再也接收不到额外数据;
  3. 一段时间之后,接收到文件结束符的应用进程调用close关闭它的socket。这导致它的TCP也发送一个FIN N;
  4. 接收到这个FIN的源发送端TCP对它进行确认。

这样每个方向上都有一个FIN和ACK。



简单理解socket

Linux Socket编程(不限Linux)

揭开socket编程的面纱

  • 8
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值