linux聊天室报告.docx
- 文档编号:9632210
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:19
- 大小:259.88KB
linux聊天室报告.docx
《linux聊天室报告.docx》由会员分享,可在线阅读,更多相关《linux聊天室报告.docx(19页珍藏版)》请在冰豆网上搜索。
linux聊天室报告
Linux程序设计
期末大作业报告
信息工程与自动化学院
专业:
计算机科学与技术
年级:
2009级
学生姓名:
徐兴繁
学生学号:
200910405214
任课教师姓名:
李英娜
任课教师职称:
讲师
摘要:
shell是一种具备特殊特殊功能的程序,它是介于使用者和UNIX、/linux操作系统之核心程序间的一个接口。
本设计主要实现一个Linux下的局域网聊天工具的设计。
该设计主要分为两部分,客户端部分和服务器部分。
设计并实现一个简单的聊天室程序,可以是终端字符界面,支持用户管理,用户名/密码注册和登录,客户端登陆到服务器聊天后,可以在聊天室内与其他用户交流(这个聊天室中的任何一个用户输入一段字符后,室内的其他用户都可以看到这句话)。
据此,聊天程序分为客户端和服务器端。
客户端对应每一个参加聊天的用户,完成从终端上输入采集并传递到服务器端和从服务器端接收信息输出显示的功能。
两个部分都使用C语言,利用vi编辑器,通过Berkeley套接口编程实现相关功能。
关键词:
linux,shell编程,聊天室,客户端,服务器,套接字。
1、期末大作业的目的
《Linux程序设计》大作业是在完成理论课程学习之后,通过大作业的方式对学生进行综合实践考核,在学生掌握Linux的基本编程知识及常用的操作命令基础上,提高学生对所学知识的应用能力,特别是:
煅炼学生搜集有关Linux资料,在资料文档的帮助下,运用Linux的基本知识及常用的操作命令来解决问题的能力。
2、大作业的基本要求
要求能完成给定的编程任务,并写出相应的大作业总结报告
2.1、根据合理的进度安排,按照程序的流程及方法,踏实地完成期末大作业的任务安排。
2.2、按照任务要求,完成各个功能模块的功能划分和程序编写,调试代码并运行。
2.3、按要求撰写大作业报告。
3、设计内容
3、1shell编程(20分)
要求:
写出2个Shell程序,每个不少于15行(如实现自己模拟shell下的cd、ls指令等),说明程序主要功能,每行给出注释;
3.1.1字符串的判断
写一个脚本,检测用户输入串的合法性,要求串由大小写字母、数字组成,无标点、特殊符号、空格。
思路:
将输入的串中非字母数字的内容删除或替换为空后若和原来输入的相同则合法,否则不合法。
#!
/bin/bash
isvalidAlphaNum()
{
compressed="$(echo$1|sed's/[^[:
alnum:
]]//g')"#替换不合要求字符为空
if["$compressed"!
="$1"];then
return1#notvalide
else
return0#valide
fi
}
#函数体,判断字串的合法性
echo-n"Enterinput:
"#-n强制不换行
readinput#读取内容存到input中,无$符号
if!
isvalidAlphaNum"&input";then#加引号,否则可能会出错。
echo"invalide"
exit1
else
echo"valide"
fi
exit0
运行截图:
3.1.2月份的截取转换
输入一个“monthdayyear”格式的日期串,程序将处理”month”为其英文单词的前三个字母,第一个字母大写,其余的小写。
思路:
首先判断month是数字、还是单词,若是数字,则可查“数字—month”映射表(自定义case结构);若是单词,则取前三个字母,并格式化。
#!
/bin/bash
monthnoToName()
{
case$1in
1)month="Jan";;2)month="Feb";;
3)month="Mar";;4)month="Apr";;
5)month="May";;6)month="Jun";;
7)month="Jul";;8)month="Aug";;
9)month="Sep";;10)month="Oct";;
11)month="Nov";;12)month="Dec";;
*)echo"$0:
Unknownnumericmonthvalue$1">&2;exit1#default,
esac#
return0
}
if[$#-ne3];then#若参数个数不为3,则有误
echo“Usage:
$0monthdayyear”
exit1
fi
#判断参数1是数字还是单词,方法替换串中所有数字,若结果为空,则为数字,否则为单词。
if[-n$(echo$1|sed‘s/[[:
digit:
]]//g’)]#-n检测串是为空
then
monthnoToName$1#数字
else
#取第一个字母并将其变为大写,再将结果与取出的第二三字母组合
month=”$(echo$1|cut–c1|tr'[:
lower:
]''[:
upper:
]')“
month=”$month$(echo$1|cut-c2-3|tr'[:
upper:
]''[:
lower:
]')”
fi
echo$month$2$3#输出结果
exit0
运行截图:
3、2聊天室编程(50分)
设计并实现一个简单的聊天室程序,可以是终端字符界面,支持用户管理,用户名/密码注册和登录,客户端登陆到服务器聊天后,可以在聊天室内与其他用户交流(这个聊天室中的任何一个用户输入一段字符后,室内的其他用户都可以看到这句话)。
据此,聊天程序分为客户端和服务器端。
客户端对应每一个参加聊天的用户,完成从终端上输入采集并传递到服务器端和从服务器端接收信息输出显示的功能。
3.2.1需要实现的主要功能
(1)客户端输入服务器IP和端口号
(2)服务器成功启动
(3)每个客户端可以找到服务器,并可以与服务器进行连接
(4)客户端与服务器可以实现通讯
3.2.2客户端功能模块
(1)连接服务器
连接服务器之前需要解析服务器地址,创建套接字,设置相关参数。
(2)发送消息功能
3.2.3服务器功能模块
3.2.4代码实现:
(1)客户端代码
#include
#include
#include
#include
#include
#include
#include
#include
#defineTRUE1
#definePORT1000
staticintsockfd;
voidrecvfromserver()//接受服务器消息线程入口函数
{
charmes[1024];
intnbytes=0;
while
(1)
{
memset(mes,0,sizeof(mes));
nbytes=read(sockfd,mes,sizeof(mes));
if(nbytes>0)
{
mes[nbytes]='\0';
printf("%s\n",mes);
}
}
pthread_exit(NULL);
}
intmain(intargc,char*argv[])
{
//intsockfd;
charbuffer[1024];
structsockaddr_inserver_addr;
structhostent*host;
intportnumber,nbytes;
char*strhost="127.0.0.1";
charclientname[20];
charpassword[20];
charmes[1024];
intthr_id;/*threadIDforthenewlycreatedthread*/
pthread_tp_thread;/*thread'sstructure*/
if(argc!
=1)
{
fprintf(stderr,"Usage:
%s\a\n",argv[0]);
exit
(1);
}
if((host=gethostbyname(strhost))==NULL)
{
fprintf(stderr,"Gethostnameerror\n");
exit
(1);
}
/*客户程序开始建立sockfd描述符*/
printf("正在建立套接口...\n");
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
fprintf(stderr,"SocketError:
%s\a\n",strerror(errno));
exit
(1);
}
/*客户程序填充服务端的资料*/
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(PORT);
server_addr.sin_addr=*((structin_addr*)host->h_addr);
printf("套接口创建成功,正在链接服务器...\n");
/*客户程序发起连接请求*/
if(connect(sockfd,(structsockaddr*)(&server_addr),sizeof(structsockaddr))==-1)
{
fprintf(stderr,"ConnectError:
%s\a\n",strerror(errno));
exit
(1);
}
/*连接成功了*/
printf("链接服务器成功\n欢迎来到聊天室!
\n");
printf("请输入你的用户昵称:
\n");
scanf("%s",clientname);
printf("请输入登录密码:
\n");
scanf("%s",password);
printf("\n登陆成功");
//write(sockfd,clientname,sizeof(clientname));
printf("\n开始聊天@(\"Quit\"断开连接)\n\n");
thr_id=pthread_create(&p_thread,NULL,recvfromserver,NULL);
while
(1)
{
memset(buffer,0,sizeof(buffer));
memset(mes,0,sizeof(mes));
scanf("%s",buffer);
strcat(mes,clientname);
strcat(mes,":
");
strcat(mes,buffer);
//printf("mainthread%s\n",mes);
if((write(sockfd,mes,sizeof(mes)))==-1)
{
fprintf(stderr,"WriteError:
%s\n",strerror(errno));
exit
(1);
}
if(strcmp(buffer,"Quit")==0)
{
break;
}
}
/*结束通讯*/
close(sockfd);
exit(0);
}
(2)服务器代码
#include
#include
#include
#include
#include
#include
#include
#include
#defineMAXLINE1000//在一条消息中最大的输出字符数
#defineLISTENQ20//最大监听队列
#definePORT1000//监听端口
#defineMAXFD20//最大的在线用户数量
void*get_client(void*);
intsockfd,i;
staticintmaxi=0;//maxi表示当前client数组中最大的用户的i值
staticintclient[MAXFD];
voidrecvandsend(void)//监听转发线程入口函数
{
intindex=0;
intnbytes=0;
charbuffer[1024];
intlen;
intoutindex=0;
while
(1)
{
if(maxi>0)
{
memset(buffer,0,sizeof(buffer));
nbytes=0;
//index++;
nbytes=read(client[index++],buffer,sizeof(buffer));
//printf("%d,%d\n",index,client[index]);
if(nbytes>0)
{
buffer[nbytes]='\0';
printf("%s\n",buffer);
outindex=0;
while(outindex if(write(client[outindex++],buffer,sizeof(buffer))==-1) { fprintf(stderr,"WriteError: %s\n",strerror(errno)); exit (1); } } } if(index>=maxi) index=0; } pthread_exit(NULL); } intmain(intargc,char*argv[]) { //intclient_fd[LISTENQ],clientnum=0;; structsockaddr_inserver_addr; structsockaddr_inclient_addr; intsin_size,portnumber; charhello[]="Hello! AreYouFine? \n"; intthr_id;/*threadIDforthenewlycreatedthread*/ pthread_tp_thread;/*thread'sstructure*/ intnew_fd=0; memset(client,0,sizeof(client)); if(argc! =1) { fprintf(stderr,"Usage: %sportnumber\a\n",argv[0]); exit (1); } /*服务器端开始建立socket描述符*/ if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) { fprintf(stderr,"Socketerror: %s\n\a",strerror(errno)); exit (1); } /*服务器端填充sockaddr结构*/ bzero(&server_addr,sizeof(structsockaddr_in)); server_addr.sin_family=AF_INET; server_addr.sin_addr.s_addr=htonl(INADDR_ANY); server_addr.sin_port=htons(PORT); /*捆绑sockfd描述符*/ if(bind(sockfd,(structsockaddr*)(&server_addr),sizeof(structsockaddr))==-1) { fprintf(stderr,"Binderror: %s\n\a",strerror(errno)); exit (1); } printf("服务器监听端口%d...\n",PORT); /*监听sockfd描述符*/ if(listen(sockfd,LISTENQ)==-1) { fprintf(stderr,"Listenerror: %s\n\a",strerror(errno)); exit (1); } thr_id=pthread_create(&p_thread,NULL,recvandsend,NULL); printf("欢迎来到聊天室\n"); while (1) { /*服务器阻塞,直到客户程序建立连接*/ if(maxi>=20) { printf("以达到人数上线\n"); continue; } sin_size=sizeof(structsockaddr_in); if((new_fd=accept(sockfd,(structsockaddr*)(&client_addr),&sin_size))==-1) { fprintf(stderr,"Accepterror: %s\n\a",strerror(errno)); exit (1); } /*fprintf(stderr,"Servergetconnectionfrom%s\n",inet_ntoa(client_addr.sin_addr));*/ client[maxi++]=new_fd; printf("\n新用户进入聊天室%d\n",new_fd-3); } close(sockfd); exit(0); } 3.2.4设计结果截图: 服务器: 第一个访客 第二个访客 第三个访客 4、小结: 通过本次设计对Linux课程的shell编程以及网络聊天室的设计,确实积累和总结了不少的经验,锻炼了我的独立工作和实际动手能力,加深了对计算机网络中socket工作原理及其相互联系的认识,提高了对复杂的综合性实践环节具有分析问题、解决问题、概括总结的实际工作能力,对网络编程项目的开发、设计过程有初步认识。 本次设计中也存在很多问题,一开始的客户端和服务器不能连接成功,还有就是当已经有用户开始聊天之后,新进来的用户发送的信息不能在之前的客户端看到,经过多次修改和查阅资料完成设计。 有新用户进来的时候虽然服务器能监听到,但是没有实时刷新给其他的客户端,导致其他用户看不到信息。 经过多次修改几乎满足了老师给的要求,能够简单的网络聊天功能。 但是由于设计时间较短,还存在很多问题,还有待于我们进一步完善其功能。 但我从中学到了不少的道理,真正的理解到,理论与实践之间还是有很大的距离,这必将有利于我们以后的学习。 使我明白,在以后的学习中,要不断的完善自己的知识体系结构,注意理论与实践的结合,学知识关键是要学活,这样所学到的东西才真正的学以致用,才达到了学习的真正目的。 5、参考文献 (1)BruceMolayUnix/Linux编程实践教程清华大学出版社,2004 (2)王群,许中万.Linux优势分析[J].计算机与现代化,2003(10): 7-8 (3)张饶学,Linux网络编程[M].北京: 清华大学出版社,2000 附件二 项目 得分 平时成绩 大作业成绩 总分 评语 教师签字: 2012年6月7日
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linux 聊天室 报告