您的位置:首页 > 理论基础 > 计算机网络

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

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

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

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

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

1.TCP/IP是什么

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

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

上面的例子告诉我们TCP/IP是用来干什么的,即它是用来让网络之间的进程通信时使用的。那么什么是TCP/IP?TCP/IP(Transmission 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中的函数如下图:



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

客户端的流程如下:

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

服务器端的流程如下:

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

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

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

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



第一次握手:客户端尝试连接服务器,向服务器发送syn包(同步序列编号Synchronize Sequence Numbers),syn=j,客户端进入SYN_SEND状态等待服务器确认

第二次握手:服务器接收客户端syn包并确认(ack=j+1),同时向客户端发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态

第三次握手:第三次握手:客户端收到服务器的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中的四次握手释放连接的过程,请看下图:



图示过程如下:

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

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

简单理解socket

Linux Socket编程(不限Linux)

揭开socket编程的面纱
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: