1、Linux系统下TFTP 和QT下聊天程序设计安徽工业大学嵌入式系统及应用综合实验报告Linux系统下TFTP 和QT下聊天程序设计姓名:学号:专业:年级:指导教师:2011年6月日课前资料: 参考资料查阅工具:man,如man ls,man make; C编写手册,机器上“linux c参考”; Shell编写手册,机器上“linux shell参考“; Makefile编写手册,机器上“makefile参考“; Awk编写手册,机器上“awk参考“; 经典书籍,学习linux,unix的最佳书籍“Linux,unix shell编程指南“一、 实验题目:熟悉linux操作系统下最简单实用的
2、通信程序socket.最好能全部完成,否则按照完成情况打分。二、 实验目的:通过对socket的编写,可以了解linux下最简单实用的进程通信方法,为后续信号灯、消息队列等学习奠定基础。三、 实验设备及环境:1. 硬件设备:PC机一台2. 软件环境:安装Linux操作系统,并安装相关的程序开发环境,如C C+tshbsh等编程语言环境。四、 实验内容及要求:(1)用C语言编程实现linux简单的聊天室功能。 用户程序命名为client.c;服务器程序命名为server.c 绑定端口等信息见实验方法内容; 要求client可以通过socket连接server 在client,提示输入服务器ip
3、若连接server 的socket建立成功,返回提示信息 Client输入的聊天内容在client端(多个client端)和server端同时显示; 多个client可同时接入server,进入聊天室,最多支持20个client; Client端输入quit退出连接,server端提示client退出。 可选择使用多线程实现多客户端; 其他细节见输出结果; 五、实验方法内容1. 需要的头文件#include#include#include#include#include#include#include#include#include#include#include2. 主要的常量变量客户端:#
4、define TRUE 1#define PORT 5000int quit=0; /quit表示是否用户确定退出服务器端:#define MAXLINE 1000 /在一条消息中最大的输出字符数#define LISTENQ 20 /最大监听队列#define PORT 5000 /监听端口#define MAXFD 20 /最大的在线用户数量void *get_client(void *); int i,maxi=-1;/maxi表示当前client数组中最大的用户的i值int clientMAXFD;3. 主要模块客户端:int main(void)void *get_server(vo
5、id* sockfd) /get_server函数,用于接受服务器转发的消息服务器端: int main() void *get_client(void *sockfd) /运行get_client函数,处理用户请求六代码考虑大家没做过,给几个例子:参考socket编程.pdf/* 客户端程序client.c */#include #include #include #include #include #include #include #include #define TRUE 1#define PORT 5000static intsockfd;void recvfromserver()
6、/接受服务器消息线程入口函数 char mes1024; intnbytes=0; while(1) memset(mes,0,sizeof(mes); nbytes=read(sockfd,mes,sizeof(mes); if(nbytes0) mesnbytes=0; printf(%sn,mes); pthread_exit(NULL);intmain(intargc, char *argv)/ intsockfd; char buffer1024; structsockaddr_inserver_addr; structhostent *host; intportnumber,nby
7、tes; char strhost16; char clientname20; char mes1024; intthr_id; /* thread ID for the newly created thread */ pthread_tp_thread; /* threads structure */ if(argc!=1) fprintf(stderr,Usage:%s an,argv0); exit(1); printf(请输入服务器ip地址n); scanf(%s,strhost); if(host=gethostbyname(strhost)=NULL) fprintf(stderr
8、,Gethostname errorn); exit(1); /* 客户程序开始建立sockfd描述符 */ printf(正在建立套接口.n); if(sockfd=socket(AF_INET,SOCK_STREAM,0)=-1) fprintf(stderr,Socket Error:%san,strerror(errno); exit(1); /* 客户程序填充服务端的资料 */ bzero(&server_addr,sizeof(server_addr); server_addr.sin_family=AF_INET; server_addr.sin_port=htons(PORT)
9、; server_addr.sin_addr=*(structin_addr*)host-h_addr); printf(套接口创建成功,正在链接服务器.n); /* 客户程序发起连接请求 */ if(connect(sockfd,(structsockaddr *)(&server_addr),sizeof(structsockaddr)=-1) fprintf(stderr,Connect Error:%san,strerror(errno); exit(1); /* 连接成功了 */ printf(链接服务器成功n欢迎来到聊天室n); printf(请输入你的用户昵称n); scanf(
10、%s,clientname);/ write(sockfd,clientname,sizeof(clientname); printf(nn开始聊天吧(Quit断开连接)nn); 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); /
11、printf(main thread %sn,mes); if(write(sockfd,mes,sizeof(mes)=-1) fprintf(stderr,Write Error:%sn,strerror(errno); exit(1); if(strcmp(buffer,Quit)=0) break; /* 结束通讯 */ close(sockfd); exit(0);/* 服务器程序 (server.c) */#include #include #include #include #include #include #include #include #define MAXLINE 1
12、000 /在一条消息中最大的输出字符数#define LISTENQ 20 /最大监听队列#define PORT 5000 /监听端口#define MAXFD 20 /最大的在线用户数量void *get_client(void *); intsockfd,i;static int maxi=0;/maxi表示当前client数组中最大的用户的i值static int clientMAXFD;void recvandsend(void) /监听转发线程入口函数 int index=0; intnbytes=0; char buffer1024; intlen; intoutindex=0;
13、 while(1) if(maxi0) memset(buffer,0,sizeof(buffer); nbytes=0; /index+; nbytes=read(clientindex+,buffer,sizeof(buffer);/ printf(%d,%dn,index,clientindex); if(nbytes0) buffernbytes=0; printf( %sn,buffer); outindex=0; while(outindex=maxi) index=0; pthread_exit(NULL);intmain(intargc, char *argv)/ intcli
14、ent_fdLISTENQ,clientnum=0; structsockaddr_inserver_addr; structsockaddr_inclient_addr; intsin_size,portnumber; char hello=Hello! Are You Fine?n; intthr_id; /* thread ID for the newly created thread */ pthread_tp_thread; /* threads structure */ intnew_fd=0; memset(client,0,sizeof(client); if(argc!=1)
15、 fprintf(stderr,Usage:%s portnumberan,argv0); exit(1); /* 服务器端开始建立 socket 描述符 */ if(sockfd=socket(AF_INET,SOCK_STREAM,0)=-1) fprintf(stderr,Socket error:%sna,strerror(errno); exit(1); /* 服务器端填充sockaddr结构 */ bzero(&server_addr,sizeof(structsockaddr_in); server_addr.sin_family=AF_INET; server_addr.sin
16、_addr.s_addr=htonl(INADDR_ANY); server_addr.sin_port=htons(PORT); /* 捆绑sockfd描述符 */ if(bind(sockfd,(structsockaddr *)(&server_addr),sizeof(structsockaddr)=-1) fprintf(stderr,Bind error:%sna,strerror(errno); exit(1); printf(服务器监听端口%d.n,PORT); /* 监听sockfd描述符 */ if(listen(sockfd,LISTENQ)=-1) fprintf(st
17、derr,Listen error:%sna,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_s
18、ize)=-1) fprintf(stderr,Accept error:%sna,strerror(errno); exit(1); /*fprintf(stderr,Server get connection from %sn,inet_ntoa(client_addr.sin_addr);*/ clientmaxi+=new_fd; printf(n新用户进入聊天室%dn,new_fd); close(sockfd); exit(0); 七、实验结果1. 执行结果 服务器打开 客户端打开,并输入了地址,昵称 服务器端显示 客户端2进入 服务器显示 张三输入 李四端显示 服务器显示 李四输
19、入 张三显示 服务器显示2. 结果分析这是一个聊天室程序,可以实现群聊的功能,即当某个客户发出消息后,服务器和其他个客户端都能收到此消息。且能够显示客户端的用户名。但客户端退出聊天室后,服务器和其他在线客户端会有提示。实现群聊的机制是:当某个客户端需要发送消息是,它将此消息发送给服务器,服务器再将此消息转发给各客户端,各客户端之间是无连接的,即相互之间不能直接通信。因此,在服务器中,有两个线程,主线程用来监听是否有客户端登录服务器,若有,建立与其连接的套接字,并存入在线客户序列里,辅助线程是接收转发线程,其依次读取个客户端,看是否有消息送达,若有,取出,并转发给各其他客户端。在客户端也有两个线
20、程,主线程用来向服务器发送消息,辅助线程用来接收服务器发出的消息。存在的问题是:1.当有用户下线是,虽会在服务器和各客户端提示用户下线,但是并未删除其在服务器中的套接字,致使后来用户不能进入。2.服务器的辅助线程对各客户端采取轮流监听的策略,但是因为使用read() 函数会阻塞线程,致使出现各客户端必须按登陆顺序依次发言的尴尬情况。经过查找,可以使用select()函数跨过阻塞,正在试验中。八、实验总结通过这次实验,熟悉了linux下的socket网络编程的基本步骤,和一些基本函数调用,并对多线程有了了解,但对线程的调度还是很模糊,需要深入学习和多加练习。教 师 评 价评定项目ABCD评定项目ABCD算法正确界面美观,布局合理程序结构合理操作熟练语法、语义正确解析完整实验结果正确文字流畅报告规范题解正确其他:评价教师签名:年月日
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1