2022年网络编程实验报告要点 .pdf
精品文档。1欢迎下载网络编程课程设计报告题目: 基于 Linux 网络聊天室的设计姓名: 陈佳悦陈雄兰学院: 信息科学技术学院专业: 网络工程班级: 网络工程 102 学号: 19310213 19310214 指导教师 : 薛 卫职称:副教授基于 Linux 网络聊天室的设计摘要:本课程设计是在Linux 环境下基于 Socket 进行开发的。系统服务器端和名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 13 页 - - - - - - - - - 精品文档。2欢迎下载客户端组成。 服务端程序通过共享存储区存储聊天数据,并发送给每个连接的客户端。通过多路复用的子进程实现服务端与多个客户端之间的数据发送与接收。可以在单机上开辟两个窗口分别运行客户、服务器的程序。 本方案经 gcc 调试器调试成功,可以在机网络聊天中使用。关键词:网络聊天; linux ;socket 1相关概念及技术1.1 网络套接字编程1.1.1 套接字基本概念套接字是通信的基石,是支持TCP/IP 协议的网络通信的基本操作单元。可以将套接字看作不同主机间的进程进行双向通信的端点,它构成了单个主机内及整个网络间的编程界面。 套接字存在于通信域中, 通信域是为了处理一般的线程通过套接字通信而引进的一种抽象概念。套接字通常和同一个域中的套接字交换数据(数据交换也可能穿越域的界限,但这时一定要执行某种解释程序)。各种进程使用这个相同的域互相之间用Internet协议簇来进行通信。1.1.2 套接字工作原理要通过互联网进行通信, 你至少需要一对套接字, 其中一个运行于客户机端,我们称之为 ClientSocket,另一个运行于服务器端, 我们称之为 ServerSocket 。根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。所谓服务器监听, 是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。所谓客户端请求, 是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。 为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。所谓连接确认,是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求, 它就响应客户端套接字的请求,建立一个新的线程, 把服务器端套接字的描述发给客户端, 一旦客户端确认了此描述, 连接就建立好了。 而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。1.1.3 linux中 socket 的基本应用:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 13 页 - - - - - - - - - 精品文档。3欢迎下载服务端建立套接字的大致步骤:(1)建立 socket 。(2)bindPort 绑定特定的端口。(3)listen 监听特定的端口。(4)accept, 当有客户端连接服务器端口时,accept 接收信息,并返回新的套接字描述符,提供给操作(5)根据实际需求, write,read,send,recv等操作(6)关闭套接字。客户端大致步骤:1)创建 socket. 2)根据服务器地址, connect 连接到特定服务器。3)write,read等读写操作。4)关闭套接字。1.2 客户/ 服务器模型应用程序之间为了能顺利地进行通信,一方通常需要处于守候状态, 等待另一方请求的到来。 在分布式计算中, 一个应用程序被动地等待, 而另一个应用程序通过请求启动通信的模式就是客户服务器模式。客户/ 服务器模型的典型运行过程包括五个主要步骤:(1)服务器监听相应窗口的输入。(2)客户机发出请求。(3)服务器接收到此请求。(4)服务器处理此请求,并将结果返回给客户机。(5)重复上述过程,直至完成一次会话过程任务。运作过程如下:响应 Request 响应请求请求 Request 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 13 页 - - - - - - - - - 精品文档。4欢迎下载1.3 多路复用技术多路复用一般有以下几种技术: (1) 非阻塞通信技术 : 将文件管道设为非阻塞通信方式, 每隔一段时间对他们实行一次轮询 , 以判断是否可以进行读写操作。(2) 信号驱动的异步 I/O 技术。 首先, 异步 I/O 是基于信号机制的 , 并不可靠。 其次, 单一的信号不足以提供更多的信息来源。还是需要辅助以其他的手段, 实现有很高的难度。(3)select()技术。在 BSD 中提供了一种可以对多路I/O 进行阻塞式查询的方法 select()。它提供同时对多个I/O 描述符进行阻塞式查询的方法。(4) 子进程技术。应用多个子进程 , 每一个对一个单工阻塞方式通信。所有子进程通过IPC 和父进程进行通信。父进程掌管所有信息。该聊天室即采用此种子进程技术。1.4 相关函数调用(1) Socket() 作用: socket 函数为客户机或服务器创建一个sokcet 格式: int socket(int family,int type,int protocol); 参数说明: Family:表示地址族,可以去AF_UNLX 和 AF_INT 。其中, AF_UNLX 只能够用于单一的 UNIX系统进程间通信 ;AF_INT 是针对 Internet的,因而可以允许在远程主机之间通信,实验中使用AF_INT 。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 13 页 - - - - - - - - - 精品文档。5欢迎下载 Type:网络程序所采用的通信协议, 可以取 SOCK_STREAM或 SOCK_DGRAM。 其中,SOCK_STREAM表明使用的是 TCP协议,这样提供按顺序的、可靠的、双向、面向连接的比特流; SOCKE_DGRAM表明使用的是 UDP协议,这样只会提供定长、不可靠、无连接的通信。(2)bind( ) 格式: int bind(int sockfd,struct sockaddr *addr,int addrlen); 参数说明: Sockfd :socket 的文件描述符号。 Sockaddr :表示名字所用的一个数据结构,用来保存地址( 包括 IP 地址和端口 ) Addrlen:设置结构大小长度。(3)listen() 格式: int listen(int sockfd, int backlog); 作用:监听连接信号,和accepted 函数合同。参数说明: Sockfd :表示 socket 调用返回的文件描述符。 Backlog :表示接入队列允许的连接数目,大多数系统允许20 个,也可以子定义510 个。(4)accept() 格式: Int accept (int sockfd, void *addr, int *addrlen); 作用:与 listen函数合用,监听信息、接收客户端请求。参数说明: Sockfd:表示 socket 的文件描述符。 Addr:表示指向局部的数据结构struct sockaddr-in的指针。 Addrlen:表示地址的长度。(5)connect() 格 式:int connect( int sockfd , struct sockaddr *serv_addr , int addrlen); 作用:在面向连接的系统中客户及连接服务器时使用,connect 必须在 bind 后使用。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 13 页 - - - - - - - - - 精品文档。6欢迎下载参数作用: Sockfd :表示 socket 的文件描述符。 Serv-addr :表示村访目的端口和ip 地址(套接字)的数据结构。(6)send() 和 recv() 格式 1:Int send (int sockfd, const vod *msg,int len, int flags); 功能:发送信息。格式 2:Int recv (int sockfd , void *buf,int len, usigned int flags); 作用:用于流式socket 、数据报 socket 内部之间的通信。(7)bindPort() 格式: int bindPort(unsigned short int port) 作用:创建套接字,并绑定到指定端口。参数说明:指定所指定的端口号。(8)fork() 作用:创建一个新的子进程,而这个子进程是父进程的副本,接下来这两个进行就由操作系统调度,直到程序执行结束。2. 系统设计与功能分析2.1 整体程序设计:服务端程序通过共享存储区存储聊天数据,并发送给每个连接的客户端; 服务端程序和客户端程序都是通过父子进程分别负责发送和接收数据的,以避免数据冲撞 . 2.1.1 服务器端程序设计:(1) 建立服务器端,创建共享存储区,便于客户与客户之间的信息交流,及服务端的记录。(2) 创建 socket 套接字 , 并绑定到指定端口, 监听套接字(客户套接字)。(3) 在监听过程中接受客户端连接,并发送问候信息。(4) 接收到客户端连接的信息后开始创建子进程,其中父进程用于接受信息,子进程用于发送信息,实现多线程操作。2.1.2 客户端程序设计:(1)建立一个客户端的socket 套接字,绑定客户端套接字连接服务端。(2)连接成功后,创建子进程,其中父进程用于接受信息,子进程用于发送信息。(3)创建子进程成功后,可以进行客户端与客户端的通信聊天。2.2 系统功能 :名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 13 页 - - - - - - - - - 精品文档。7欢迎下载(1)创建服务器后,服务器创建了共享存储区,方便客户与客户之间聊天信息的记录,包括聊天具体内容及时间记录。(2)客户端创建后如 xx(需输入 ip 地址、端口号、用户名如下面截图实例:./c 127.0.0.1 6666 xx), 在服务器的监听下,很快xx 就与服务器建立了连接。(3)与此同时另一客户yy 创建,同理 yy 也与服务器建立了连接,此时两客户端就可以通过服务器建立连接,开始聊天。(4)在服务器上,也一直记录了客户端间的聊天记录具体信息。3. 主要算法及流程图图 5 为客户端主程序的流程图;图 6 为客户端 get() 函数即文件下载的流程图;图 7 为服务器端出程序流程图;4. 系统开发调试与运行环境?开发环境:本系统是在Linux 环境下用 C语言结合网络编程知识开发的。?运行环境:虚拟机: Vmware 操作系统: Ubuntu-11.10-desktop 5. 实验运行效果截图演示:第一部分:(1)服务器端:编译s.c 即服务器端程序,运行,显示如下:说明连接成功,服务器正在监听,有无客户端请求。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 13 页 - - - - - - - - - 精品文档。8欢迎下载(2)客户端 1:编译 c.c 即客户端程序,运行指定IP 地址为本机地址,端口号为 6666,用户名为 xx,显示如下:说明已经进入群聊的聊天室。(2)客户端 2:编译 c.c 即客户端程序,运行指定IP 地址为本机地址,端口号为 6666,用户名为 yy,显示如下:说明已经进入群聊的聊天室。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 13 页 - - - - - - - - - 精品文档。9欢迎下载第二部分:(1)客户端 1:开启聊天功能, xx 在界面上发起对话(2)客户端 2:当 xx 在自己的客户端 1 界面上发起对话,客户端2 界面显示内名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 13 页 - - - - - - - - - 精品文档。10欢迎下容,同时 yy 也向 xx 即客户端 1 发送内容。(3)服务器端:服务器接收客户端1 (xx) 发送的内容并且传送给客户端2 (yy) ,同时接收 yy 发送的内容再转发给xx。第三部分:聊天截图名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 13 页 - - - - - - - - - 精品文档。11欢迎下名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 13 页 - - - - - - - - - 精品文档。12欢迎下虽然实现的只是一个功能相对比较简单的程序,但是期间受益匪浅, 一方面是考察了这一个学期来对linux内核编程的学习成果, 检验了综合运用所学知识点的能力,尝试将书本的理论知识运用到实践中,另一方面在实践中加深了对理论知识的理解,发现理论到实际所出现的问题、困难,以及寻找解决的方案,与此同时能够让我们认清自己在学习Socket 编程不足之处和薄弱环节,并加以弥补和巩固,并且通过对线程同步程序的设计和运用,进一步的巩固用Socket 编程的能力,并且也更好的理解操作系统的工作形式。第一次采用采用C/S架构并且在linux环境下编写程序,比较新鲜但是期间我们也遇到了很多的困难,例如:(1)socket 实现过程:服务器端的recv() 函数,不同情况下,返回的次数不清楚,其实是对返回的条件不清楚,后来经过查阅资料以及对事例的研究,基本清楚了它的运用。(2)在实现多线程的时候,调用pthread_exit()函数使线程退出。需要注意的地方:一是,主线程中如果从main 函数返回或是调用了exit函数退出主线程,则整个进程终止,此时所有的其他线程也将终止。另一种是,如果主线程调用 pthread_exit函数,则仅仅是主线程消亡,进程不会结束,其他线程也不会结束,知道所有的线程都结束时, 进程才结束。 刚开始接触的时候只是对上课的时候老师给的例子基本分析了解,但是实现的时候一直无法实现多线程,即并发名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 12 页,共 13 页 - - - - - - - - - 精品文档。13欢迎下执行。从编程中体会颇多,学到了很多东西,懂得了怎样建立socket 套接字,在客户端和在服务器端的不同之处,TCP套接字以及加锁解锁和条件变量的作用。也懂得了网络通信中服务器需要循环等待客户端连接进来,然后创立一个单独的线程来监听该客户端的行为动作。同时加强了我对 TCP/IP Socket 编程这门课程的认识,并且也复习了以前学习到的知识,自己的逻辑思维能力也得到了一定的提高。通过这次课程的大作业, 懂得了理论与实际相结合是很重要的,只有理论是远远不够的, 只有把所学的理论知识与实践相结合起来,从理论知识与实践相结合,从理论中得出结论, 才是真正的知识, 才能提高自己的事迹动手能力和独立思考的能力。另一方面由于对 linix的生疏以及编程能力的欠缺, 我们实现的只是皮毛功能,所以之后要对这方面更加重视实践,争取实现更完善的功能。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 13 页,共 13 页 - - - - - - - - -