socket的异步通讯机制

前言:在网络socket编程中,开发着常常没有异步通讯的经验,客户端发完数据就阻塞等待,或者开启一个进程或线程来专门处理通讯问题。很少有人能写出一个异步通讯的优雅流程,从而适应当前大规模平行计算的要求。我想就这个问题以FTP为例和大家分享一下。问题:FTP 是一个建立在TCP/IP之上,在客户端和服务器之间用于文件传输的标准协议。要实现一个完整的客户端文件下载过程,一般有三个步骤:通过三次握手建立TCP的控制信道,然后发送用户名和密码,通过用户认证;还需要指定下载文件的模式和接收建立数据信道传输
摘要由CSDN通过智能技术生成

前言:

在网络socket编程中,开发着常常没有异步通讯的经验,客户端发完数据就阻塞等待,或者开启一个进程或线程来专门处理通讯问题。很少有人能写出一个异步通讯的优雅流程,从而适应当前大规模平行计算的要求。我想就这个问题以FTP为例和大家分享一下。

问题:

FTP 是一个建立在TCP/IP之上,在客户端和服务器之间用于文件传输的标准协议。要实现一个完整的客户端文件下载过程,一般有三个步骤:

  1. 通过三次握手建立TCP的控制信道,然后发送用户名和密码,通过用户认证;还需要指定下载文件的模式和接收建立数据信道传输的必要参数。
  2. 在客户端和服务器之间建立一个数据信道。然后通过控制信道发送文件操作命令(上传或者下载)和文件名,再通过数据信道传输文件数据。
  3. 文件传输结束后,关闭数据信道。并且通过控制信道通知客户端文件传输结束。这时客户端可以关闭控制信道,结束FTP

在这个三个步骤中,第一步就足以包括异步通讯的所有机制。基于篇幅,本文将着重分析这一步。这一步涉及到很多TCP的交互操作。由于TCP是基于流的工作方式,一次系统调用不一定把数据或者指令发送完毕,这就需要等待对方有能力接收数据后,再次发送或者接收。另外,即使客户端发送完某个指令后,也必须等待服务器的回答才能继续下面的工作。从面试结果来看,大部分面试者都用了阻塞等待的方式。也就是直接调用socket的send或者recv命令发送或者接收数据;在等待服务器回答时,用select系统调用,直到超时。这样的实现会引起如下问题:

  1. 阻塞等待的过程中,这个进程没办法作别的工作,尤其是定时器更新等任务。一旦socket传输结束,就有可能引发超时异常。即使没有超时,CPU也会因为阻塞引起重新调度,从而CPU的利用率会大大降低。
  2. 为了避免阻塞原进程,有的面试者会开启一个专门通讯进程来处理通讯。但是进程的代价比较高,如果客户端要同时和数万个服务器连接,这样客户端很快会拓机。如果用线程来处理,虽然可以降低代价,但也无法避免。再就是如果新的线程需要对原进程的某个数据结构进行读写,这样可能会需要加锁,程序性能会变差,也增加维护的难度。

在上述两个问题中,如果能够用进程来避免阻塞,一般可以认为是一个有潜力的开发者。如果能过有人用线程来处理,并且用锁或者其他机制来进行数据同步的话,就算比较有经验了。但是一个真正的异步通讯还需要进一步优化。

异步解决方案:

异步解决方案本质上是基于事件的驱动。为了详细解释这个机制,本文将先用时序图描述具体问题,然后用状态机来进行功能设计,最后给出伪代码。

时序图:

需要先用时序图来描述FTP第一步的通讯过程,这是下面两步的基础。
FTP控制信道的建立

状态机:

从时序图可以看出,FTP的客户端和服务器有多次交互。异步通讯,就是一个指令发送完成后,在收到回应之前,可以让这个进程能去作别的工作。等收到回应后,再从发送完成的那个代码点继续运行。要实现这个机制,我们可以用状态来记住那些代码点,这样自然就可以想到用有限状态机来进行设计。如何定义FTP的状态机呢?严格的说,每一次系统调用如果需要根据返回的结果才能决定下一步的动作的话,就需要定义一个状态。根据时序图建立的FTP客户端状态机如下三个图所示:

FTP控制信道状态机1

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值