c语言使用消息队列实现Linux主机板私有聊天功能整个客户端和服务器功能

上周,我的朋友正在开发一个在 Linux 主板上实现私人聊天功能的项目。
他打算利用消息队列技术,将客户端和服务器设置为不同的进程,通过消息队列进行通信。

客户端的操作如下:首先定义一个自定义的结构体来存储消息类型和内容。
然后通过ftok函数生成唯一的键值,并使用msgget创建或获取消息队列。
发送消息时,使用msgsnd函数将包含聊天内容的结构放入队列中。
用户输入的聊天信息通过fgets从标准输入中获取,然后通过指定的msgid和消息内容大小发送出去。

服务器端类似,使用ftok生成键值,msgget创建或获取消息队列。
通过msgrcv函数接收消息,并使用msgid和消息内容大小从队列中获取数据。
为了限制访问,客户端和服务端生成相同的key值并调用msgget来保证双方可以访问同一个消息队列。

客户端发送类型1 消息,表示聊天内容,服务器收到后回复类型2
但是在实际应用中,我们还是要考虑错误处理和安全检查,比如限制聊天内容长度、控制客户端数量等。

2 02 3 年,我帮他想了一个办法,在客户端和服务端都添加异常捕获,比如捕获msgget和msgsnd中可能出现的错误。
此外,您还可以设置最大消息长度。
如果超过此长度,将提示用户重新输入。

我刚刚想到了另外一件事,我们还可以设置一个用户列表来限制同时在线的客户端数量。
如果达到限制,新连接的客户端可以等待,直到用户注销。

算了,我们现在就这样做吧。
由你决定。

qq for linux怎么设置按enter键发送消息

【Linux系统】进程间通信-System V消息队列

说实话,SystemV消息队列用起来还是挺有趣的。
我在开发Linux服务器时遇到过很多使用它的场景,尤其是那些需要多个后台进程相互传输状态信息的场景。
例如,我构建了一个监控系统,该系统使用消息队列将数据从各种传感器实时传输到中央处理进程。

我们先来说一下生命周期独立性的特点。
我印象特别深刻。
我曾经写过一个测试程序,使用IPC_RMID创建了一个消息队列并删除了它。
我发现只要程序重新启动,队列就自动返回。
当时我就很困惑,以为自己写了一个bug。
后来看了手册才知道这个东西是遵循内核而不是进程的。
这让我明白为什么一些系统级工具,比如crontab,需要以root权限使用——因为普通用户无法删除内核的东西。

三种销毁方法中,我最常用的是msgctl函数。
例如,我有一个定期扫描配置文件的服务程序。
如果发现配置发生改变,则使用IPC_RMID直接删除队列。
请注意,此时应解决权限问题。
如果队列权限设置得太严格,您的程序甚至可能无法删除它创建的队列。
我就遇到过一次这种情况。
我编写了一个守护进程,并希望在重新启动时清理剩余的队列。
因此,由于umask参数的原因,导致程序运行时没有足够的权限。
最后我不得不编写一个 systemd 服务单元并在启动时更改 umask 来解决问题。

至于ftok函数,使用时一定要小心。
我已经写了一个小工具,想使用消息队列与另一个进程进行通信。
结果ftok使用的文件路径写错了,导致生成的key和其他的冲突。
当时确实很困惑,查了很久才发现是路径问题。
后来我总结了我的经验。
最好控制一下ftok所使用的文件的权限,比如配置文件存放的目录,这样就不容易出错。

在消息格式方面,我建议你了解一下mtype字段。
刚开始使用的时候,一直想着直接传递通道,却发现接收端不知道如何按类型进行过滤。
后来我改用long类型作为帖子ID,加上结构,一下子就清晰多了。
我记得在一个项目中,mtype 没有正确完成,导致消息堆积,最终 CPU 崩溃——接收进程正在等待一种从未到达的特定类型的消息,占用了所有资源。

在实现封装方面,我在编写MsgQueue类时,修复了阻塞模式下的msgflg参数,以避免客户端错误。
但现在看起来它可以配置,例如通过添加构造函数参数来允许用户可以选择是阻塞还是非阻塞。
不过当时我没有这么做,主要是觉得项目时间比较紧,想先保证基本功能能用起来。

最后,给大家一些个人建议。
在权限管理方面,创建队列时常见使用06 6 6 ,但请记住系统umask可以将其更改为较小的值。
我在一个项目中遇到了这个陷阱。
在开发过程中我认为06 6 6 没有问题。
但部署到生产环境后,由于系统策略的原因,实际权限变成了04 4 4 ,导致其他进程无法发送消息。
所以现在当我编写代码时我总是添加“mode |= ~umask;”强制所需的权限。
错误处理也是如此。
IPC功能的反馈值得仔细检查。
我见过人们编写的代码只是忽略了 msgsnd 的失败。
结果,消息在我们没有意识到的情况下就丢失了。
最后,系统日志中有许多“消息队列已满”警告。
SystemV消息队列确实很强大,但是使用时要小心。
特别是对于生命周期,不要期望队列在进程完成后自动消失,除非您使用IPC_RMID或重新启动系统。
后来做新项目的时候,我更喜欢使用更现代的通信方式,比如Unix Socket或者Redis,但是SystemV这个老东西,关键时刻还是蛮靠谱的。