Linux系统下TFTP 和QT下聊天程序设计.docx

上传人:b****7 文档编号:10804843 上传时间:2023-02-23 格式:DOCX 页数:19 大小:102.75KB
下载 相关 举报
Linux系统下TFTP 和QT下聊天程序设计.docx_第1页
第1页 / 共19页
Linux系统下TFTP 和QT下聊天程序设计.docx_第2页
第2页 / 共19页
Linux系统下TFTP 和QT下聊天程序设计.docx_第3页
第3页 / 共19页
Linux系统下TFTP 和QT下聊天程序设计.docx_第4页
第4页 / 共19页
Linux系统下TFTP 和QT下聊天程序设计.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

Linux系统下TFTP 和QT下聊天程序设计.docx

《Linux系统下TFTP 和QT下聊天程序设计.docx》由会员分享,可在线阅读,更多相关《Linux系统下TFTP 和QT下聊天程序设计.docx(19页珍藏版)》请在冰豆网上搜索。

Linux系统下TFTP 和QT下聊天程序设计.docx

Linux系统下TFTP和QT下聊天程序设计

安徽工业大学

嵌入式系统及应用综合实验报告

Linux系统下TFTP和QT下聊天程序设计

 

姓名:

学号:

专业:

年级:

指导教师:

2011年6月日

课前资料:

●参考资料查阅工具:

man,如manls,manmake;

●C编写手册,机器上“linuxc参考”;

●Shell编写手册,机器上“linuxshell参考“;

●Makefile编写手册,机器上“makefile参考“;

●Awk编写手册,机器上“awk参考“;

●经典书籍,学习linux,unix的最佳书籍“Linux,unixshell编程指南“

一、实验题目:

熟悉linux操作系统下最简单实用的通信程序socket.最好能全部完成,否则按照完成情况打分。

二、实验目的:

通过对socket的编写,可以了解linux下最简单实用的进程通信方法,为后续信号灯、消息队列等学习奠定基础。

三、实验设备及环境:

1.硬件设备:

PC机一台

2.软件环境:

安装Linux操作系统,并安装相关的程序开发环境,如C\C++\tsh\bsh等编程语言环境。

四、实验内容及要求:

(1)用C语言编程实现linux简单的聊天室功能。

⏹用户程序命名为client.c;服务器程序命名为server.c

⏹绑定端口等信息见实验方法内容;

⏹要求client可以通过socket连接server

◆在client,提示输入服务器ip

◆若连接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

#include

2.主要的常量变量

客户端:

#defineTRUE1

#definePORT5000

intquit=0;//quit表示是否用户确定退出

服务器端:

#defineMAXLINE1000//在一条消息中最大的输出字符数

#defineLISTENQ20//最大监听队列

#definePORT5000//监听端口

#defineMAXFD20//最大的在线用户数量

void*get_client(void*);

inti,maxi=-1;//maxi表示当前client数组中最大的用户的i值

intclient[MAXFD];

3.主要模块

客户端:

intmain(void)

void*get_server(void*sockfd)

//get_server函数,用于接受服务器转发的消息

服务器端:

intmain()

void*get_client(void*sockfd)//运行get_client函数,处理用户请求

六.代码

考虑大家没做过,给几个例子:

参考socket编程.pdf

/*******客户端程序client.c************/

#include

#include

#include

#include

#include

#include

#include

#include

 

#defineTRUE1

#definePORT5000

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;

charstrhost[16];

charclientname[20];

charmes[1024];

intthr_id;/*threadIDforthenewlycreatedthread*/

pthread_tp_thread;/*thread'sstructure*/

if(argc!

=1)

{

fprintf(stderr,"Usage:

%s\a\n",argv[0]);

exit

(1);

}

printf("请输入服务器ip地址\n");

scanf("%s",strhost);

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);

//write(sockfd,clientname,sizeof(clientname));

printf("\n\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);

}

/*******服务器程序(server.c)************/

#include

#include

#include

#include

#include

#include

#include

#include

#defineMAXLINE1000//在一条消息中最大的输出字符数

#defineLISTENQ20//最大监听队列

#definePORT5000//监听端口

#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);

}

close(sockfd);

exit(0);

}

七、实验结果

1.执行结果

●服务器打开

●客户端打开,并输入了地址,昵称

●服务器端显示

●客户端2进入

●服务器显示

●张三输入

●李四端显示

●服务器显示

●李四输入

●张三显示

●服务器显示

2.结果分析

这是一个聊天室程序,可以实现群聊的功能,即当某个客户发出消息后,服务器和其他个客户端都能收到此消息。

且能够显示客户端的用户名。

但客户端退出聊天室后,服务器和其他在线客户端会有提示。

实现群聊的机制是:

当某个客户端需要发送消息是,它将此消息发送给服务器,服务器再将此消息转发给各客户端,各客户端之间是无连接的,即相互之间不能直接通信。

因此,在服务器中,有两个线程,主线程用来监听是否有客户端登录服务器,若有,建立与其连接的套接字,并存入在线客户序列里,辅助线程是接收转发线程,其依次读取个客户端,看是否有消息送达,若有,取出,并转发给各其他客户端。

在客户端也有两个线程,主线程用来向服务器发送消息,辅助线程用来接收服务器发出的消息。

存在的问题是:

1.当有用户下线是,虽会在服务器和各客户端提示用户下线,但是并未删除其在服务器中的套接字,致使后来用户不能进入。

2.服务器的辅助线程对各客户端采取轮流监听的策略,但是因为使用read()函数会阻塞线程,致使出现各客户端必须按登陆顺序依次发言的尴尬情况。

经过查找,可以使用select()函数跨过阻塞,正在试验中。

八、实验总结

通过这次实验,熟悉了linux下的socket网络编程的基本步骤,和一些基本函数调用,并对多线程有了了解,但对线程的调度还是很模糊,需要深入学习和多加练习。

教师评价

评定项目

A

B

C

D

评定项目

A

B

C

D

算法正确

界面美观,布局合理

程序结构合理

操作熟练

语法、语义正确

解析完整

实验结果正确

文字流畅

报告规范

题解正确

其他:

 

评价教师签名:

 

年月日

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工作范文 > 行政公文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1