一种同时支持socket同步和异步通信方式的实现机制
技术领域
本发明属于相关网络通信技术领域,具体涉及一种同时支持socket同步和异步通信方式的实现机制。
背景技术
在进行网络客户(Client)端的socket编程时,常常会见到同步和异步这两种通信方式。
所谓同步方式,就是在客户端发出一个功能调用时,在没有得到结果之前,该调用会一直等待,不会返回。这时程序是处于阻塞的,只有接收到返回值才往下执行其他的命令。
异步方式就是当客户端一个异步过程调用发出之后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知或回调来通知调用者。
有些大型的操作系统,如Windows,会同时提供这两种通信方式的socket API。但是对于很多应用于嵌入式操作系统的TCP/IP协议栈一般只支持同步方式的socket API。因为同步方式实现起来比较简单,而且一般也能满足用户一般的需求了。但在某些应用场景,比如,在移动通信的模块中,需要通过AT命令来创建和管理多个socket连接时,通常的做法是针对每个socket连接创建一个应用层的务(task)来进行管理。否则,如果只在一个task中处理的话,当其中的一个socket连接调用了同步方式的API之后,在得到结果之前,该task就会被堵塞,其他socket连接就得不到处理。但这种创建多个task的方式需要消耗掉很多系统资源,而且管理起来很不方便。在这种情况下,如果采用异步方式的话,只需要一个Task来处理就可以了,这样可以大大节约系统资源,而系统资源对于嵌入式系统来说是非常宝贵的。
所以,需要提供一种同时能够支持同步和异步通信方式的socket API来解决这个问题。
发明内容
本发明的目的在于提供一种同时支持socket同步和异步通信方式的实现机制,以解决当前应用于一般的嵌入式系统的TCP/IP协议栈只支持同步方式的socket API不能很好地解决一些特殊的应用场景下的使用问题。
为实现上述目的,本发明提供如下技术方案:
一种同时支持socket同步和异步通信方式的实现机制,包括了socket API,应用层Task、接收Task和发送Task。
当外部(比如别的task)需要应用层Task开始建立连接时,就会发一个对应的事件(Event)给应用层Task,应用层Task就会调用API socket()来创建一个socket,如果是异步方式的,就会在创建socket成功之后,注册socket callback 函数fun1,并与该socket进行绑定。如果是同步方式的话,则无此步骤。这是后续区分同步和异步方式的标志。
创建完socket之后,应用层Task根据实际需求调用相关的socket API来进行处理。如果是与发送数据相关的API,则需要发送信号量给发送Task,告诉发送Task有数据要发送,如果是与接收数据相关的Task,则无此步骤。在调用这些socket API的时候,如果是异步模式,就可以直接返回了,如果是同步模式,需要等待接收Task或者是发送Task处理完成相关的流程之后发送过来的信号量,才可以继续往下执行并返回。
当驱动程序接收到数据之后,会通知接收Task,接收Task开始对数据包进行处理。处理完成之后,如果是异步方式,就调用在创建socket时注册的callback 函数fun1,进行相应的业务处理,之后发送事件(Event)给应用层Task,通知应用层Task数据接收的结果。如果是同步方式,就发送应用层Task正在等待的信号量给应用层Task,这样应用层Task接收到这个信号量之后就可以继续往下执行了。
由于应用层Task在调用与发送数据相关的API时,会发送信号量给发送Task。发送Task接收到这个信号量之后,会根据各个连接(connection)的状态,发送数据包。等发送完成之后,会根据是同步还是异步方式进行相应的处理。如果是异步方式,就调用在创建socket时注册的callback 函数fun1,进行相应的业务处理,之后发送事件(Event)给应用层Task,通知应用层Task数据发送的结果。如果是同步方式,就发送应用层Task正在等待的信号量给应用层Task,这样应用层Task接收到这个信号量之后就可以继续往下执行了。
优选的,所述在应用层Task调用API socket()来创建一个socket时,如果是异步方式,就会在创建socket成功之后,注册socket callback 函数fun1,并与该socket进行绑定。如果是同步方式,则无此步骤。这是区分同步和异步方式的标志。
优选的,所述不管是采用异步方式API的应用层Task和采用同步方式API的应用层Task都是基于消息或者是事件驱动的。
优选的,所述当socket API处理完各自的相关的事情之后,会根据是同步还是异步方式来进行不同的流程,判断是同步还是异步的标准就是是否注册了socket callback函数fun1,如果注册了就是异步方式,否则是同步方式。
优选的,所述接收Task只处理与接收数据相关业务,发送Task只处理与发送数据相关的业务,而且发送Task和接收Task都是基于消息或者是事件驱动的。
优选的,所述如果应用层Task调用的是跟发送数据相关的socket API时,需要发送信号量给发送Task,告知发送Task有数据要发送。
优选的,所述如果是异步方式,则调用socket API时不需要等待就直接返回了。如果是同步方式,对于大部分的socket API,则需要等待接收Task或者是发送Task处理完相关的流程之后发来的信号量之后才可以继续往下执行并返回,有少数不需要与服务器端交互的API则不需要等待,直接返回,如socket()
优选的,所述如果是异步方式,则接收Task或者发送Task在处理完相关的流程之后,会调用在创建socket时注册的callback函数fun1进行相应的业务处理,然后发送事件(Event)给应用层Task,通知应用层Task数据处理的结果。
优选的,所述的socket API仍然是标准的外部接口,没有改动,修改的是socketAPI的内部实现。
与现有技术相比,本发明提供了一种同时支持socket同步和异步通信方式的实现机制,具备以下有益效果:
本发明公开了一种基于嵌入式系统的同时支持socket同步和异步两种通信方式的实现机制。该实现机制仅通过修改socket API的内部实现,但不修改其外部调用接口来实现。使得用户很方便地对上层应用程序进行移植,并根据应用程序的需要选择是同步方式或者是异步方式。解决了一般嵌入式系统的TCP/IP协议栈仅支持同步方式而导致不能很好地满足一些特殊应用场景的应用需求。该实现机制能够更好地满足了应用程序多样化的需求,具有很好的适用性和应用前景。
附图说明
附图用来提供对本发明的进一步理解,并且构成说明书的一部分,与本发明的实施例一起用于解释本发明,并不构成对本发明的限制,在附图中:
图1为本发明提出的一种同时支持socket同步和异步通信方式的实现机制的应用层Task的处理流程图示意图;
图2为本发明提出的一种同时支持socket同步和异步通信方式的注册socketcallback 流程示意图;
图3为本发明提出的一种同时支持socket同步和异步通信方式的socket API处理流程示意图;
图4为本发明提出的一种同时支持socket同步和异步通信方式的接收Task的处理流程示意图;
图5为本发明提出的一种同时支持socket同步和异步通信方式的发送Task的处理流程示意图。
具体实施方式
下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
请参阅图1-5,本发明提供一种技术方案:
一种同时支持socket同步和异步通信方式的实现机制,在嵌入式系统中,出于对任务的合理划分和为了保证实时性,一般都会有一个任务(Task)来专门负责接收从驱动程序中收到的TCP/IP数据包,并进行处理,在这里命名为接收Task,同时也有一个任务(Task)来负责数据包的发送,在这里命名为发送Task,而socket API是在应用层的任务(Task)来调用,作为客户端的socket API,主要包括socket()、connect()、recv()、recvfrom()、send()、sendto()和close()等,其中,socket()是在客户端本地创建一个socket,是不需要跟服务器端交互的,对于UDP来说,调用了close()也不需要跟服务器端交互。
进一步,不管是采用异步方式socket API的应用层Task和采用同步方式socketAPI的应用层Task都是基于消息或者是事件驱动的。如图1所示,当外部需要应用层task开始建立连接时,就会发一个对应的事件Event给应用层Task,应用层Task就会调用APIsocket()来创建一个socket。如图2所示,如果是异步方式的,就会在创建socket成功之后,注册socket callback 函数fun1,并与该socket进行绑定,如果是同步方式的话,则无此步骤。
进一步,当socket API处理完各自的相关的事情之后,会根据是同步还是异步方式来进行不同的流程,判断是同步还是异步的标准就是是否注册了socket callback 函数fun1,如果注册了就是异步方式,否则是同步方式。如图3所示,异步方式,会注册一个callback 函数fun2,并与该连接connection绑定,该callback 函数的实现与API需要实现的目的有关,如果是与发送数据相关的API(如connect()、send()/sendto()和TCP的close()),则发送信号量sem2给发送Task,告诉发送Task有数据要发送,如果是与接收数据相关的API,则无此步骤。
进一步,如果调用的是跟发送数据相关的API时,会发送信号量sem2给发送Task。如图5所示,发送Task接收到这个信号量之后,会根据各个连接connection的状态,发送数据包,等发送完成之后,会调用已注册的callback函数fun2来处理相关业务。之后会根据是同步还是异步方式进行相应的处理。
进一步,如果是同步方式,发送Task就发送信号量sem1给应用层Task,这样应用层Task接收到这个信号量sem1之后就可以继续往下执行了,如图3所示。如图5所示,之后发送Task返回继续等待信号量sem2,从而可以很好的进行信息重新选定。
进一步,如果是异步方式,发送Task调用已注册的socket callback 函数fun1,进行相应的业务处理,之后发送事件(Event)给应用层Task,通知应用层Task数据发送的结果,并注销掉已注册的callback函数fun2。如图5所示,之后返回继续等待信号量sem2,等待应用层Task有数据需要发送时再次触发。
进一步,接收Task只处理与接收数据相关业务。如图4所示,当驱动程序接收到数据之后,会通知接收Task,接收Task开始对数据包进行处理,然后根据数据包的包头找到对应的连接connection。然后调用已注册的callback函数fun2来处理相关业务,之后会根据是同步还是异步方式进行相应的处理。
进一步,如果是异步方式,接收Task就调用已注册socket callback 函数fun1,进行相应的业务处理,之后发送事件(Event)给应用层Task,通知应用层Task数据接收的结果。并注销掉已注册的callback函数fun2。然后返回继续等待驱动程序的通知。
进一步,如果是同步方式,接收Task发送信号量sem1给应用层Task,这样应用层Task接收到这个信号量sem1之后就可以继续往下执行了,如图4所示。之后返回继续等待驱动程序的通知。
本发明的工作原理及使用流程:本发明同时支持socket同步和异步通信方式的实现机制客户端的socket API,主要包括socket()、connect()、recv()、recvfrom()、send()、sendto()和close()等。当采用采用异步方式API的应用层Task和采用同步方式API的应用层Task的时候,都是基于消息或者是事件驱动的,如图1所述。若要建立的是TCP连接,就要调用API connect(),接收数据和发送数据,就调用recv()、send(),当UDP连接,从而创建完socket之后,就可以直接调用socket API recvfrom()、sendto()来收发数据了,对于这些socket API,与同步和异步方式相关的处理流程如图3所示。在图3中,如果是异步方式,会注册一个callback 函数fun2,并与该连接connection绑定,该callback 函数的实现与API需要实现的目的有关,如果是与发送数据相关的API(如connect()、send()/sendto()和TCP的close()),则发送信号量sem2给发送Task,告诉发送Task有数据要发送,如果是与接收数据相关的API,则无此步骤,之后就可以直接返回了。如果是同步方式,则要先创建信号量sem1,并与当前连接connection绑定,然后注册callback函数fun2,如果是需要发送数据的API,则发送信号量sem2给发送Task。接下来就开始等待信号量sem1。如果是与接收数据相关的API,接收Task在接收到数据包之后,会发送信号量sem1给当前的调用socketAPI的应用层Task,如图4所示。而如果是与发送数据相关的API,在发送Task发送数据完成之后,会发送信号量sem1给当前的应用层Task。当接收到sem1之后,socket API又可以继续往下执行了,然后是注销掉之前注册的callback函数fun2,删除之前创建的信号量sem1,最后就返回了。
而当驱动程序接收到数据之后,会通知接收Task,接收Task开始对数据包进行处理,之后会根据是同步还是异步方式进行相应的处理。如果是异步方式,就调用在创建socket时注册的socket callback 函数fun1,进行相应的业务处理,之后发送事件Event给应用层Task,通知应用层Task数据接收的结果,并注销掉已注册的callback函数fun2。然后返回继续等待驱动程序的通知。如果是同步方式,就发送信号量sem1给应用层Task,这样应用层Task接收到这个信号量sem1之后就可以继续往下执行了。之后返回继续等待驱动程序的通知。
如果应用层Task调用的是跟发送数据相关的API时,会发送信号量sem2给发送Task。发送Task接收到这个信号量之后,会根据各个连接connection的状态,发送数据包。等发送完成之后,会调用已注册的callback函数fun2来处理相关业务,之后会根据是同步还是异步方式进行相应的处理。如果是异步方式,就调用在创建socket时注册socketcallback 函数fun1,进行相应的业务处理,之后发送事件Event给应用层Task,通知应用层Task数据发送的结果,并注销掉之前在步骤2中注册的callback函数fun2。然后返回继续等待信号量sem2,等待下次应用层Task的再次触发。如果是同步方式,就发送信号量sem1给应用层Task,这样应用层Task接收到这个信号量sem1之后就可以继续往下执行了,之后返回继续等待信号量sem2,等待下次应用层Task的再次触发。
需要说明的是,不建议在同一个应用层的Task中,既采用同步方式的API,又采用异步方式的API,不然异步方式的socket API可能得不到及时的处理。而在同一个Task中,可以同时处理多个异步方式的socket,而且不会相互影响。
尽管已经示出和描述了本发明的实施例,对于本领域的普通技术人员而言,可以理解在不脱离本发明的原理和精神的情况下可以对这些实施例进行多种变化、修改、替换和变型,本发明的范围由所附权利要求及其等同物限定。