linux网络编程之system v消息队列(三)
今天继续学习System V消息队列,主要是用消息队列来重新实现回射客户/服务器的功能,来进一步掌握消息队列,下面开始:

下面用一个示意图来表示其实现原理:

那么服务器端是如何区分消息是发送给不同的客户端的呢?很自然想到的就是用类型进行区分,给不同客户端发送的是不同类型的消息,客户端则接收对应类型的消息,那这个类型用什么标识不同的客户端呢?进程的pid则是一个很好的类型方案,如下:



根据这个流程,下面来用代码实现一下:
首先实现服务器端:

其中服务器要干的事,就是不断地接收类型为1的消息,并且将其消息回射给不同的客户端,所以下面来实现一下:

然后取出前4个字节,代表客户端的进程ID,如下:

接下来则将真正的内容打印出来,并且将其回射给客户端:

这样服务端就编写好了,接下来编写客户端,其实现跟服务器很类似:

首先是不断地从键盘中获取数据,发送给服务器:

接下来,则是处理从服务器回射回来的数据,其写法跟服务端的很类似:

【说明】:为啥不清空前四个字节,如果清空了则下次发送消息时又得存,所以为了简单,就不清空了。
好了,下面来编译运行:

下面来发送消息:

从以上实验结果来看,回射功能是没问题,但是,服务器的回显只打印了一条消息,这看样子是个小bug,下面来解决一下:

改为:

而主要原因是由于服务器回显给客户端时造成type的改变,如下:

所以在客户端每次循环时,就得每次都指定一下msg.mtype = 1,否则,实际上客户端是自已发给自己,就造成了客户端有回显,而服务端没有,改变之后,再次运行:

发现服务器的消息显示还有些问题,原因其实很简单,就是由于没有清空之前数据造成,修改如下:

下面最后运行一下:

实际上,这里还存在一种隐含的问题,会产生“死锁”现象,下面来分析一下产生的原因:



避免死锁的方案需要采用另外一种实现方式,这里只是探讨一下,可以自己去实现:



好了,今天先学到这,下回见~
浙公网安备 33010602011771号