安徽工业大学嵌入式系统及应用综合实验报告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操作系统下最简单实用的通信程序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<stdlib.h>#include<stdio.h>#include<string.h>#include<errno.h>#include<netdb.h>#include<sys/types.h>#include<netinet/in.h>#include<sys/socket.h>#include<sys/wait.h>#include<unistd.h>#include<pthread.h>2.主要的常量变量客户端:#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 client[MAXFD];3.主要模块客户端:int main(void)void *get_server(void* sockfd)//get_server函数,用于接受服务器转发的消息服务器端:int main()void *get_client(void *sockfd) //运行get_client函数,处理用户请求六.代码考虑大家没做过,给几个例子:参考socket编程.pdf/******* 客户端程序client.c ************/#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <netdb.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#define TRUE 1#define PORT 5000static int sockfd;void recvfromserver() //接受服务器消息线程入口函数{char mes[1024];int nbytes=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);}int main(int argc, char *argv[]){// int sockfd;char buffer[1024];struct sockaddr_in server_addr;struct hostent *host;int portnumber,nbytes;char strhost[16];char clientname[20];char mes[1024];int thr_id; /* thread ID for the newly created thread */ pthread_t p_thread; /* thread's structure */ 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,"Gethostname error\n");exit(1);}/* 客户程序开始建立sockfd 描述符*/printf("正在建立套接口...\n");if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){fprintf(stderr,"Socket Error:%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=*((struct in_addr *)host->h_addr);printf("套接口创建成功,正在链接服务器...\n");/* 客户程序发起连接请求*/if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1) {fprintf(stderr,"Connect Error:%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("main thread %s\n",mes);if((write(sockfd,mes,sizeof(mes)))==-1){fprintf(stderr,"Write Error:%s\n",strerror(errno));exit(1);}if(strcmp(buffer,"Quit")==0){break;}}/* 结束通讯*/close(sockfd);exit(0);}/******* 服务器程序(server.c) ************/#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <netdb.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#define MAXLINE 1000 //在一条消息中最大的输出字符数#define LISTENQ 20 //最大监听队列#define PORT 5000 //监听端口#define MAXFD 20 //最大的在线用户数量void *get_client(void *);int sockfd,i;static int maxi=0;//maxi表示当前client数组中最大的用户的i值static int client[MAXFD];void recvandsend(void) //监听转发线程入口函数{int index=0;int nbytes=0;char buffer[1024];int len;int outindex=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<maxi)if(write(client[outindex++],buffer,sizeof(buffer))==-1){fprintf(stderr,"Write Error:%s\n",strerror(errno));exit(1);}}}if(index>=maxi)index=0;}pthread_exit(NULL);}int main(int argc, char *argv[]){// int client_fd[LISTENQ],clientnum=0;;struct sockaddr_in server_addr;struct sockaddr_in client_addr;int sin_size,portnumber;char hello[]="Hello! Are You Fine?\n";int thr_id; /* thread ID for the newly created thread */pthread_t p_thread; /* thread's structure */ int new_fd=0;memset(client,0,sizeof(client));if(argc!=1){fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]);exit(1);}/* 服务器端开始建立socket 描述符*/if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){fprintf(stderr,"Socket error:%s\n\a",strerror(errno));exit(1);}/* 服务器端填充sockaddr 结构*/bzero(&server_addr,sizeof(struct sockaddr_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,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1) {fprintf(stderr,"Bind error:%s\n\a",strerror(errno));exit(1);}printf("服务器监听端口%d...\n",PORT);/* 监听sockfd 描述符*/if(listen(sockfd,LISTENQ)==-1){fprintf(stderr,"Listen error:%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(struct sockaddr_in);if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1){fprintf(stderr,"Accept error:%s\n\a",strerror(errno));exit(1);}/*fprintf(stderr,"Server get connection from %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.结果分析这是一个聊天室程序,可以实现群聊的功能,即当某个客户发出消息后,服务器和其他个客户端都能收到此消息。