课程设计报告课程名称:Unix课程设计设计题目:利用消息队列实现多进程通信过程姓名:专业:网络工程班级:学号:计算机科学与技术学院网络系2013年12月30日成绩:哈尔滨理工大学计算机科学与技术学院网络系课程设计报告一、选题背景在UNIX程序设计中消息队列是使用频率最高的几个对象之一,它常应用于对等进程间的通信和客户—服务器之间的通信。采用消息队列作为货物托运渠道可以弥补以下缺陷:(1)消息队列是一种先进先出的队列型数据结构,可以保证先送的货物先到达,后送的货物后到达,避免了插队现象。(2)消息队列将输出的信息进行了打包处理,这样就可以保证以每个消息为单位进行接收了。(3)消息队列还可以将货物进行分类服务,标记各种类别的服务,这样就可以根据货物类别分别出货。消息队列是IPC对象的一种与同样提供先进先出服务的管道相比,它有如下特点:(1)消息队列提供了消息的自动拆分功能,同时不能接收两次发送的消息。(2)消息队列提供了不完全随机读取的服务,引入消息类型后,一个消息队列在逻辑上可以化身为多个不同消息类型的链表,用户可以自主选择接收某条逻辑链表上的消息,而不必依次接收队列的首条消息。(3)消息队列提供了完全异步的读写服务。基于以上背景,我们发现利用消息队列实现进程间的通信可以为我们提供方便,也会是通信效率更为提高。二、设计思路可以采用客户-服务器结构,其中服务器端实现各个用户的登录并存储相关信息,客户端通过服务器端获取当前登录用户信息,然后各客户进程通过消息队列实现双向通信。编程实现两个进程间的通信,一个server(服务器)进程,一个client(客户)进程。在client(客户)进程下选择注册或者登陆。若是注册,则server(服务器)进程分给该客户一个新的登陆账号。多个客户的账号存储在register.txt文件中。若是选择登陆,登陆成功后服务器进程会显示登陆成功,否则显示登陆失败。登陆后输入你要发送消息的对方的账号,输入账号后,服务器方显示该账号是否合理,如合理,即可实行通信。三、主要问题的解决方法和关键技术实现密码格式登录与注册,通过帐号显示用户名,显示发送消息的日期四、程序流程图哈尔滨理工大学计算机科学与技术学院网络系实验室实验报告五、原程序清单//client.c#includestdio.h#includeunistd.h#includesys/types.h#includesys/stat.h#includesys/ipc.h#includesys/msg.h#includetermio.h#includetime.hstructmsgbuf{longtype;charbuf[1024];};structmsgbuf0{longtype;pid_tpid;charusername[48];charpassword[48];charnumber[28];};voidfunc();voidregist();//注册voidpassw();voidinputpassw(char*P);voidenter();//登录哈尔滨理工大学计算机科学与技术学院网络系实验室实验报告voiddata();voidstol(char*);//加密voidltos(char*);//解密structmsgbuf_msgbuf;structmsgbuf0_msgbuf0,_msgbuf1;intmsgid,index,flag;longnumber;pid_tpid,pid1;FILE*fpr;charusername[16],password[16],buf[64],inde[4],flg[4];voidmain(){//28pid_tpid=getpid();if((msgid=msgget(0x4321,0666|IPC_CREAT))0){fprintf(stderr,msgget()failed.\n);return;}fprintf(stderr,注册pleaseinput'z',登录input'd':);scanf(%s,buf);memset(&_msgbuf0,0,sizeof(_msgbuf0));if(buf[0]==100){enter();//登录}elseif(buf[0]==122){regist();//注册}}voidfunc(){memset(&_msgbuf,0,sizeof(_msgbuf));_msgbuf.type=atoi(_msgbuf0.username)+100;while(msgrcv(msgid,&_msgbuf,sizeof(_msgbuf.buf),_msgbuf.type,IPC_NOWAIT)!=-1){fprintf(stderr,%s[receice].\n,_msgbuf);memset(&_msgbuf,0,sizeof(_msgbuf));}//signal(KILL,func);}voidregist(){memset(_msgbuf0.username,0,16);memset(_msgbuf0.password,0,16);fprintf(stderr,pleaseinputusername(注册):);scanf(%s,_msgbuf0.username);getchar();if(strlen(_msgbuf0.username)3||strlen(_msgbuf0.username)16){fprintf(stderr,thelengthofusernamecann'tless3(注册)andmore哈尔滨理工大学计算机科学与技术学院网络系实验室实验报告16.\n);regist();}_msgbuf0.pid=getpid();_msgbuf0.type=2;//查询stol(_msgbuf0.username);///加密passw();//密码_msgbuf0.type=2;_msgbuf0.pid=getpid();stol(_msgbuf0.password);///加密fprintf(stderr,doyouwanttogetanumberforchat:(y/n));if(getchar()=='y'){msgsnd(msgid,&_msgbuf0,128,0);memset(&_msgbuf0,0,sizeof(_msgbuf0));msgrcv(msgid,&_msgbuf0,128,getpid()+10000,0);ltos(_msgbuf0.number);fprintf(stderr,恭喜你获得一个聊天账号:%s.\n,_msgbuf0.number);fprintf(stderr,登录pleaseinput'd':);scanf(%s,buf);if(buf[0]==100){enter();//登录}}}voidpassw(){fprintf(stderr,pleaseinputpassword(注册):);inputpassw(_msgbuf0.password);//scanf(%s,_msgbuf0.password);while(strlen(_msgbuf0.password)3||strlen(_msgbuf0.password)16){fprintf(stderr,thelengthofpasswordcann'tless3(注册)andmore16.\n);fprintf(stderr,pleaseinputpassword(注册):);inputpassw(_msgbuf0.password);//scanf(%s,_msgbuf0.password);}fprintf(stderr,pleaseinputpasswordagain(注册):);inputpassw(password);//scanf(%s,password);if(strcmp(_msgbuf0.password,password)){memset(_msgbuf0.password,0,49);memset(password,0,17);fprintf(stderr,两次输入的密码不一致,请从新填写信息。\n);passw();哈尔滨理工大学计算机科学与技术学院网络系实验室实验报告}}voidenter(){memset(&_msgbuf0,0,sizeof(_msgbuf0));fprintf(stderr,pleaseinputnumber(登录):);scanf(%s,_msgbuf0.number);getchar();while((strlen(_msgbuf0.number)!=8)||(atoi(_msgbuf0.number)100000000)||(atoi(_msgbuf0.number)10000000)){fprintf(stderr,pleaseinputnumber(登录):);scanf(%s,_msgbuf0.number);getchar();}fprintf(stderr,pleaseinputpassword(登录):);inputpassw(_msgbuf0.password);_msgbuf0.type=1;number=atoi(_msgbuf0.number);stol(_msgbuf0.number);///加密stol(_msgbuf0.password);///加密msgsnd(msgid,&_msgbuf0,128,0);memset(&_msgbuf,0,sizeof(_msgbuf));msgrcv(msgid,&_msgbuf,sizeof(_msgbuf.buf),number,0);ltos(_msgbuf.buf);sscanf(_msgbuf.buf,%01[^:]:%s,buf,username);if(!(strcmp(buf,n))){fprintf(stderr,%s登陆失败.\n.\n,username);enter();}fprintf(stderr,%s登陆成功.\n.\n,username);if((pid1=fork())0){fprintf(stderr,fork()failed.\n);return;}if(pid10){data();}if(pid1==0){while(1){memset(&_msgbuf,0,sizeof(_msgbuf));if(msgrcv(msgid,&_msgbuf,sizeof(_msgbuf.buf),number+100000000,MSG_NOERROR)!=-1){ltos(_msgbuf.buf);//解密fprintf(stderr,\n%s\n\n[send]:,_msgbuf.buf);哈尔滨理工大学计算机科学与技术学院网络系实验室实验报告memset(&_msgbuf,0,sizeof(_msgbuf));}}}}voiddata(){longnumber1;charusername1[16];structtmwhen;time_tnow;while(1){fprintf(stderr,pleaseinput你要发送对方的账号:);memset(&_msgbuf1,0,sizeof(_msgbuf1));scanf(%s,_msgbuf1.number);while((strlen(_msgbuf1.number)!=8)||(atoi(_msgbuf1.number)100000000)||(atoi(_msgbuf1.number)10000000)||(atoi(_msgbuf1.number)==number)){fprintf(stderr,pleaseinputnumberagain:);scanf(%s,_msgbuf1.number);}_msgbuf1.type=4;_msgbuf1.pid=getpid();n