基于Linux的消息队列及多线程编程实现的聊天室(一)
2013-01-09 11:18
856 查看
本程序主要是针对Linux IPC通信初学者对Linux下消息队列通信机制,多线程编程,字符串处理,链表操作,信号简单处理等基本概念的练习。
原理:
消息队列是System V支持一种IPC机制,通过类似链表的操作向一个FIFO里通过msgsnd发送用户自定义数据,进程可以通过msgrcv来接收指定类似mtype的数据,从而实现进程间通信。
主要实现了以下功能:
> 通过多个终端登录,不同终端上登录用户实现私聊
> 群聊
> 查看在线用户
> 简单注册(没有实现用户保存,类似于公共聊天室)
下面是几种操作的处理流程分析。详细代码分析见下篇博文:
/article/1433038.html
代码下载:
http://download.csdn.net/detail/mr_raptor/4976808
>> 服务器通过特定的类型mtype:1000,从消息队列上接收数据。
>> 当前登录用户将随机产生(random())的一个随机ID号作为申请用户ID,使用如下协议向服务器(mtype=1000)发送申请消息。
@msg.h
协议数据定义如下,共有4个段,以“:”作为分隔符。
CMD:FROM:TIME:DATA
CMD:表示执行的操作
FROM:表示来自哪个终端
TIME:申请时间
DATA:用户发送数据
>> 服务器在接收到用户申请请求后,从可用ID里取出可用ID号(可用ID从START_ID开始向上累加)分配给新申请用户,将其加入到服务器维护的链表里,然后将新分配ID号写回到客户端(使用客户端随机产生的ID号写回),并且以后通信都通过新的ID号作用消息队列的mtype。
@msg.h
@msg_client.c
>> 当用户在消息队列上收到消息后,按照前面说的通信协议解析(strtok())接收到的数据,格式化后依据不同的CMD操作用于分支处理。
>> 群聊消息发送给服务器,服务器收到后,遍历在线链表,向每个在线用户发送消息。@msg_svr.c
下面是分支处理代码片段:
注:本程序只能运行在一个主机上不同终端之间,不能实现跨主机通信。
运行情况如下:
服务器运行情况:
主要打印客户端的用户操作,消息转发等信息。
客户端登录:初始帮助信息
用户登录及列出在线用户:
另外一个终端登录luccy用户,列出在线用户:
私聊:
另外一个终端收到信息:
群聊,两个终端都收到信息:
退出:
另外还有文件传输功能,留给同学们自己去实现吧。
原理:
消息队列是System V支持一种IPC机制,通过类似链表的操作向一个FIFO里通过msgsnd发送用户自定义数据,进程可以通过msgrcv来接收指定类似mtype的数据,从而实现进程间通信。
主要实现了以下功能:
> 通过多个终端登录,不同终端上登录用户实现私聊
> 群聊
> 查看在线用户
> 简单注册(没有实现用户保存,类似于公共聊天室)
下面是几种操作的处理流程分析。详细代码分析见下篇博文:
/article/1433038.html
代码下载:
http://download.csdn.net/detail/mr_raptor/4976808
>> 服务器通过特定的类型mtype:1000,从消息队列上接收数据。
>> 当前登录用户将随机产生(random())的一个随机ID号作为申请用户ID,使用如下协议向服务器(mtype=1000)发送申请消息。
@msg.h
协议数据定义如下,共有4个段,以“:”作为分隔符。
// CMD:FROM:TIME:DATA #define DATA_LEN 4 #define OFT_CMD 0 #define OFT_FRM 1 #define OFT_TIM 2 #define OFT_DAT 3 #define DATA_TOK ":"
CMD:FROM:TIME:DATA
CMD:表示执行的操作
FROM:表示来自哪个终端
TIME:申请时间
DATA:用户发送数据
>> 服务器在接收到用户申请请求后,从可用ID里取出可用ID号(可用ID从START_ID开始向上累加)分配给新申请用户,将其加入到服务器维护的链表里,然后将新分配ID号写回到客户端(使用客户端随机产生的ID号写回),并且以后通信都通过新的ID号作用消息队列的mtype。
@msg.h
#define START_ID 1>> 登录用户接收到服务器分配的新ID后,开启接收消息线程等待接收来自消息队列里发送给自己的消息。
@msg_client.c
if(login() == OK) while(pthread_create(&thread, NULL, receiver_looper, NULL) < 0); break;
void * receiver_looper(void * p){ if(userid == 0) return NULL; char * data[DATA_LEN]; char * str, *subtoken; int i; while(1){ if(msgrcv(msgid, &msg_rcv, sizeof(msg_rcv), userid, 0) < 0){ perror("msgrcv"); continue; }else{
>> 当用户在消息队列上收到消息后,按照前面说的通信协议解析(strtok())接收到的数据,格式化后依据不同的CMD操作用于分支处理。
#ifdef _DEBUG printf("%s received: %s\n", __func__, msg_rcv.buffer); #endif memset(data, NULL, sizeof(data)); for(str = msg_rcv.buffer, i = 0; ; str = NULL, i++){ subtoken = strtok(str, DATA_TOK); if(subtoken == NULL) break; data[i] = subtoken; #ifdef _DEBUG printf("> data[%d] = %s\n", i, subtoken); #endif } // process received data // data format error if(i != DATA_LEN) continue; switch(data[OFT_CMD][0]){ case CMD_LIST: if(strcmp(data[OFT_FRM], TYPE_SERVER_STR)){ continue; } format_user_list(data[OFT_DAT]); break; case CMD_LOGOUT: if(strcmp(data[OFT_FRM], TYPE_SERVER_STR)){ continue; } printf("> %s ", data[OFT_DAT]); printf("%s\n", time2str(atol(data[OFT_TIM]), data[OFT_DAT])); exit(0); case CMD_CHAT: // print chat content printf("\n%s \n\t\t", data[OFT_DAT]); printf("%s\n", time2str(atol(data[OFT_TIM]), data[OFT_DAT])); printf("\n%s# ", name); fflush(stdout); break; case CMD_SEND_FILE: break; } }
>> 群聊消息发送给服务器,服务器收到后,遍历在线链表,向每个在线用户发送消息。@msg_svr.c
下面是分支处理代码片段:
case CMD_TOALL: // send to all online client p = (&msg_list_head)->next; while(p){ u= (struct user*)p; send_msg(u->id, CMD_CHAT, data[OFT_FRM], data[OFT_DAT]); p = p->next; } break;
注:本程序只能运行在一个主机上不同终端之间,不能实现跨主机通信。
运行情况如下:
服务器运行情况:
主要打印客户端的用户操作,消息转发等信息。
客户端登录:初始帮助信息
用户登录及列出在线用户:
另外一个终端登录luccy用户,列出在线用户:
私聊:
另外一个终端收到信息:
群聊,两个终端都收到信息:
退出:
另外还有文件传输功能,留给同学们自己去实现吧。
相关文章推荐
- 基于Linux的消息队列及多线程编程实现的聊天室(二)代码分析
- 基于Linux的消息队列及多线程编程实现的聊天室(一)
- Linux进程间通信(IPC)编程实践(五)消息队列实现回射客户/服务器
- linux基础编程 共享内存 通过消息队列实现同步 shmget
- TCP/IP网络编程 基于Linux编程_4 --多线程服务器端的实现
- TCP/IP网络编程 基于Linux编程_4 --多线程服务器端的实现
- linux基础编程 共享内存 通过消息队列实现同步 shmget
- linux网络编程之System V 消息队列:消息队列实现回射客户/服务器和 msgsnd、msgrcv 函数
- Linux 消息队列 实现的简单聊天室
- Linux Socket 网络编程 基于GTK+ 的多线程实现的局域网通信软件
- Linux Socket 网络编程 基于GTK+ 的多线程实现的局域网通信软件
- linux-消息队列编程实例
- Java 多线程Socket编程通讯--实现聊天室代码
- linux基础编程:进程通信之System V IPC:消息队列,信号量,共享内存
- 【Linux】消息队列--实现进程间通信
- linux编程---进程通信---消息队列
- Linux网络编程 基于tcp的多线程的服务器
- 基于Redis实现分布式消息队列(4)
- LINUX_C编程实战—第十章《进程间的通信》-消息队列
- Linux网络编程基础API(多线程实现)