网络编程课程设计报告基于linux网络聊天室设计.docx
- 文档编号:4223650
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:13
- 大小:73.60KB
网络编程课程设计报告基于linux网络聊天室设计.docx
《网络编程课程设计报告基于linux网络聊天室设计.docx》由会员分享,可在线阅读,更多相关《网络编程课程设计报告基于linux网络聊天室设计.docx(13页珍藏版)》请在冰豆网上搜索。
网络编程课程设计报告基于linux网络聊天室设计
网络编程课程设计报告
题目:
基于linux网络聊天室设计
姓名:
学院:
信息科学技术学院
专业:
网络工程
班级:
网络112班
学号:
指导教师:
职称:
副教授
2014年6月22日
基于linux网络聊天室设计
摘要:
本课程设计是在Linux环境下基于Socket进行开发的。
系统服务器端和客户端组成。
服务端程序通过共享存储区存储聊天数据,并发送给每个连接的客户端。
通过多路复用的子进程实现服务端与多个客户端之间的数据发送与接收。
可以在单机上开辟两个窗口分别运行客户、服务器的程序。
本方案经gcc调试器调试成功,可以在机网络聊天中使用。
关键词:
网络聊天;linux;socket
1.linux中socket的基本应用:
1.1服务端建立套接字的大致步骤:
(1)建立socket。
(2)bindPort绑定特定的端口。
(3)listen监听特定的端口。
(4)accept,当有客户端连接服务器端口时,accept接收信息,并返回新的套接字描述符,提供给操作
(5)根据实际需求,write,read,send,recv等操作
(6)关闭套接字。
1.2客户端大致步骤:
(1)创建socket.
(2)根据服务器地址,connect连接到特定服务器。
(3)write,read等读写操作。
(4)关闭套接字。
1.3客户/服务器模型
应用程序之间为了能顺利地进行通信,一方通常需要处于守候状态,等待另一方请求的到来。
在分布式计算中,一个应用程序被动地等待,而另一个应用程序通过请求启动通信的模式就是客户/服务器模式。
客户/服务器模型的典型运行过程包括五个主要步骤:
(1)服务器监听相应窗口的输入。
(2)客户机发出请求。
(3)服务器接收到此请求。
(4)服务器处理此请求,并将结果返回给客户机。
(5)重复上述过程,直至完成一次会话过程任务。
2.系统结构设计
2.1系统结构设计
本系统采用客户/服务器模型,在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式是客户/服务器模式(Client/Servermodel),即客户向服务器发出服务请求,服务器接收到请求后,提供相应的服务。
客户/服务器模式的建立基于以下两点:
首先,建立网络的起因是网络中软硬件资源、运算能力和信息不均等,需要共享,从而造就拥有众多资源的主机提供服务,资源较少的客户请求服务这一非对等作用。
其次,网间进程通信完全是异步的,相互通信的进程间既不存在父子关系,又不共享内存缓冲区,因此需要一种机制为希望通信的进程间建立联系,为二者的数据交换提供同步,这就是客户端/服务器模式的TCP/IP。
在客户/服务器模型中,多个相互通信的计算机都作为客户端,与网络服务器进行连接,并通过服务器进行信息的传递[4]。
所以多个客户端之间的通信就变为了客户端与服务端的通信。
服务器端和客户端的主要组成如下:
服务器端:
套接字创建函数Socket(),端口绑定函数Bind(),套接口监听函数Listen(),接受连接函数Accept(),数据收发函数Read()和Write(),以及套接口关闭函数Close()。
客户端:
套接口创建函数Socket(),套接口连接函数Connect(),数据收发函数Read()和Write(),以及套接口关闭函数Close()。
2.2通信设计
首先运行服务器端程序,通过Socket()函数会建立一个套接字,然后通过Bind()函数绑定一个端口,然后调用Listen()在套接字指定的端口上开始倾听,利用Accept()从完全建立连接的队列中接受一个连接,连接获得后使用Read()和Write()函数进行通信。
通信结束后调用Close()关闭套接字描述符。
运行客户端的程序,调用Socket()函数建立一个套接字,使用Connect()函数与服务器端进行连接,连接完成后,使用Write()和Read()与服务器端进行通信,通信结束后调用close()关闭套接字描述符。
3.1系统调用相关函数
(1)Socket()
作用:
socket函数为客户机或服务器创建一个sokcet
格式:
intsocket(intfamily,inttype,intprotocol);
参数说明:
Family:
表示地址族,可以去AF_UNLX和AF_INT。
其中,AF_UNLX只能够用于单一的UNIX系统进程间通信;AF_INT是针对Internet的,因而可以允许在远程主机之间通信,实验中使用AF_INT。
Type:
网络程序所采用的通信协议,可以取SOCK_STREAM或SOCK_DGRAM。
其中,SOCK_STREAM表明使用的是TCP协议,这样提供按顺序、可靠、双向、面向连接的比特流;SOCKE_DGRAM表明使用的是UDP协议,这样只会提供定长、不可靠、无连接的通信。
(2)bind()
格式:
intbind(intsockfd,structsockaddr*addr,intaddrlen);
参数说明:
Sockfd:
socket的文件描述符号。
Sockaddr:
表示名字所用的一个数据结构,用来保存地址(包括IP地址和端口)
Addrlen:
设置结构大小长度。
(3)listen()
格式:
intlisten(intsockfd,intbacklog);
作用:
监听连接信号,和accepted函数合同。
参数说明:
Sockfd:
表示socket调用返回的文件描述符。
Backlog:
表示接入队列允许的连接数目,大多数系统允许20个,也可以子定义5~10个。
(4)accept()
格式:
Intaccept(intsockfd,void*addr,int*addrlen);
作用:
与listen函数合用,监听信息、接收客户端请求。
参数说明:
Sockfd:
表示socket的文件描述符。
Addr:
表示指向局部的数据结构structsockaddr-in的指针。
Addrlen:
表示地址的长度。
(5)connect()
格式:
intconnect(intsockfd,structsockaddr*serv_addr,intaddrlen);
作用:
在面向连接的系统中客户及连接服务器时使用,connect必须在bind后使用。
参数作用:
Sockfd:
表示socket的文件描述符。
Serv-addr:
表示村访目的端口和ip地址(套接字)的数据结构。
(6)send()和recv()
格式1:
Intsend(intsockfd,constvod*msg,intlen,intflags);
功能:
发送信息。
格式2:
Intrecv(intsockfd,void*buf,intlen,usignedintflags);
作用:
用于流式socket、数据报socket内部之间的通信。
(7)close()和shutdown()
格式:
Close(intsockfd)
或
Intshutdown(intsockfd,inthow);
参数说明:
How的值为下面一种:
0----不允许继续接收;
1----不允许继续发送;
2---不允许继续发送和接收。
(8)有关线程的系统调用函数pthread_create()、pthread_join()
3.2实现过程
(1)监听连接
利用socket、bind、listen建立连接,步骤是:
1)先用socket函数初始化socket,创建新的sockfd。
Sockfd=socket(AF_INT,SOCK_STREAM,0)
2)此步骤涉及到IP地址及其处理过程。
参数说明:
inet_addr函数INADDR_ANY
该函数把由小数点分开的十进制IP地址转为unsingedlong类型,而在实验中所使用的为INADDR_ANY,使用利用自已的IP地址自动填充。
1)利用bind函数绑定端口和IP地址。
My_addr.sin_family=AF_INET;/*将地址族类型设定好*/
My_addr.sin_port=htons(MYPORT;/*将端口给其赋值*/
My_addr.sin_addr.s_addr=INADDR_ANY;/*用连接地址自动填充ip*/
Bind(sockfd,(stuctsockaddr*)&my_addr,sizeof(stuctsockaddr));
/*sockfd是分配的socket名字,my-addr则便是分配好的端口与IP,用bind绑定*/
2)利用listen监听请求
(2)发送请求
1)利用gethostbyname获取主机信息。
2)初始化socket端口。
3)利用connect函数将自己的IP地址等信息发送到主机,等待主机调用accept函数来接受请求。
(3)主机接收请求,进行数据通信
1)主机利用accept接收请求。
2)创建子进程,显示欢迎信息;
3)接收返回信息,显示连接成功,并推出连接;
4)关闭客户端口socket;
5)关闭服务端socket,结束子线程。
4.运行结果
(1)在编写完TCP服务端程序server.c后,用gcc–lpthread–oserver.cserver生成程序server。
(2)在编写完TCP客户端程序client.c后,用gcc–lpthread–oclient.cclient生成程序client
(3)在主机上打开一窗口,运行server。
(4)再打开另一个窗口或者在另一个主句上打开一个窗口,运行client,输入服务器的IP地址,并检查器结果的正确性。
输入:
【主】#./server
【从】#./client127.0.0.1
输出:
【主】#server:
gotconnectionfrom127.0.0.1
(5)客户端、服务器端窗口之间以及交错发送信息的方式相互发送和接收信息。
1)客户端、服务器端窗皆通过键盘输入消息内容平回车,以发送消息给对方;
2)消息中若使用空格,则作为本条消息结束及下一条消息的开始;
3)输入exit则推出运行。
开始运行后,服务器端窗口的执行顺序为:
1)键入”thisisserver”发送给客户端,如图
(1)所示。
图
(1)
2)接收客户端发来的”thisisclient”,如图
(2)所示。
图
(2)
3)输入exit结束。
开始运行后,客户端窗口的执行顺序为:
1)接收服务器端发来的消息“Thisisserver”,如图(3)所示。
图(3)
2)发送消息“Thisisclient”给服务器端如图(4)所示。
图(4)
3)键入exit结束。
上述运行结果表明,客户端与服务器端之间传递的消息已被对方成功接收。
5.总结
通过本次课程设计对Linux网络聊天室的设计,确实积累和总结了不少的经验,锻炼了我的独立工作和实际动手能力,加深了对计算机网络中socket工作原理及其相互联系的认识,提高了对复杂的综合性实践环节具有分析问题、解决问题、概括总结的实际工作能力,对网络编程项目的开发、设计过程有初步认识。
服务端源程序清单如下,文件名为server.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#defineMYPORT3490
#defineBACKLOG10
#defineMAXDATASIZE1024
intsockfd,new_fd;
pthread_taccthread,recthread;
voidrecmessage(void){
while
(1){
intnumbytes;
charbuf[MAXDATASIZE];
if((numbytes=recv(new_fd,buf,MAXDATASIZE,0))==-1){
perror("recv");
exit
(1);
}
buf[numbytes]='\0';
if(strcmp(buf,"exit")==0){
printf("Clientisclosed\n");
close(new_fd);
close(sockfd);
exit
(1);
}
printf("Client:
%s\n",buf);
}
}
voidacceptconnect(void)/*与listen函数合用,监听信息、接收客户端请求*/
{
structsockaddr_intheir_addr;
intsin_size;
sin_size=sizeof(structsockaddr_in);
if((new_fd=accept(sockfd,(structsockaddr*)&their_addr,&sin_size))==-1){
perror("accept");
exit
(1);
}
printf("server:
gotconnectionfrom%s\n",inet_ntoa(their_addr.sin_addr));
if((pthread_create(&recthread,NULL,(void*)recmessage,NULL))!
=0){
printf("Createthreaderror!
\r\n");
exit
(1);
}
}
intmain(void){
structsockaddr_inmy_addr;
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
perror("socket");
exit
(1);
}
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(MYPORT);
my_addr.sin_addr.s_addr=INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
if(bind(sockfd,(structsockaddr*)&my_addr,sizeof(structsockaddr))==-1){
perror("bind");
exit
(1);
}
if(listen(sockfd,BACKLOG)==-1){/*监听连接信号*/
perror("listen");
exit
(1);
}
if((pthread_create(&accthread,NULL,(void*)acceptconnect,NULL))!
=0){
printf("Createthreaderror!
\r\n");
exit
(1);
}
while
(1){
charmsg[MAXDATASIZE];
scanf("%s",msg);
if(send(new_fd,msg,strlen(msg),0)==-1){
perror("send");
close(new_fd);
exit
(1);
}
if(strcmp(msg,"exit")==0){
printf("Byebye!
\n");
close(new_fd);
close(sockfd);
exit
(1);
}
}
return0;
}
客户端源程序清单如下,文件名为client.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#definePORT3490
#defineMAXDATASIZE1024
intsockfd;
pthread_trecthread;
voidrecmessage(void){
while
(1){
intnumbytes;
charbuf[MAXDATASIZE];
if((numbytes=recv(sockfd,buf,MAXDATASIZE,0))==-1){
perror("recv");
exit
(1);
}
buf[numbytes]='\0';
if(strcmp(buf,"exit")==0){
printf("Serverisclosed\n");
close(sockfd);
exit
(1);
}
printf("Server:
%s\n",buf);
}
}
intmain(intargc,char*argv[]){
structhostent*he;
structsockaddr_intheir_addr;
if(argc!
=2){
fprintf(stderr,"usage:
clienthostname\n");
exit
(1);
}
if((he=gethostbyname(argv[1]))==NULL){
herror("gethostbyname");
exit
(1);
}
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
perror("socket");
exit
(1);
}
their_addr.sin_family=AF_INET;
their_addr.sin_port=htons(PORT);
their_addr.sin_addr=*((structin_addr*)he->h_addr);
bzero(&(their_addr.sin_zero),8);
if(connect(sockfd,(structsockaddr*)&their_addr,sizeof(structsockaddr))==-1)
/*在面向连接的系统中客户及连接服务器时使用*/
{
perror("connect");
exit
(1);
}
if((pthread_create(&recthread,NULL,(void*)recmessage,NULL))!
=0){
printf("Createthreaderror!
\r\n");
exit
(1);
}
while
(1){
charmsg[MAXDATASIZE];
scanf("%s",msg);
if(send(sockfd,msg,strlen(msg),0)==-1){
perror("send");
close(sockfd);
exit
(1);
}
if(strcmp(msg,"exit")==0){
printf("Byebye!
\n");
close(sockfd);
exit
(1);
}
}
return0;
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 网络 编程 课程设计 报告 基于 linux 聊天室 设计