网络编程 发送what is time 返回时间

上传人:s****a 文档编号:167965017 上传时间:2022-11-06 格式:DOCX 页数:24 大小:105.28KB
收藏 版权申诉 举报 下载
网络编程 发送what is time 返回时间_第1页
第1页 / 共24页
网络编程 发送what is time 返回时间_第2页
第2页 / 共24页
网络编程 发送what is time 返回时间_第3页
第3页 / 共24页
资源描述:

《网络编程 发送what is time 返回时间》由会员分享,可在线阅读,更多相关《网络编程 发送what is time 返回时间(24页珍藏版)》请在装配图网上搜索。

1、网络程序设计课程设计报告目录第一章 实验目的和要求11.1实验目的11.2实验要求11.3实验内容1第二章实验内容22.1对题目的分析22.2守护进程的原理3第三章设计实现43.1关键技术分析43.1.1创建守护进程43.1.2 I/O 复用的 select 函数63.1.3网络套接字函数73.2关键程序代码分析83.2.1创建守护进程83.2.2套接字编程93.2.3 I/O 复用的 select 函数103.2.4处理客户连接10心得体会11参考文献12附录 1 程序界面截图13附录2源代码14第一章 实验目的和要求1.1实验目的(1) 熟练掌握所学到的网络套接字函数;(2) 掌握UDP和

2、TCP编程关键函数;(3) 掌握多进程或多线程编程;(4) 掌握使用select实现I/O复用;(5) 掌握守护进程的编写。1.2实验要求(1) 认真阅读和掌握本实验的相关的知识点。(2) 上机编写并运行程序。(3) 保存和打印出程序的运行结果。1.3实验内容本次课程设计题目如下:(1) 实现一个并发、io复用的守护进程时间服务器,要求当客户端向服务器 发送“what s time?”字符串时,服务器回应当时的系统时间字符串。(2) 实现一个类似于“飞鸽传书”的文件传输软件,要求其具有并发并发性、 IO复用性。当用户使用软件时要求指明“目的ip地址”和“要传输的文件的路 径”。第二章实验内容2

3、.1对题目的分析我们选择实验的题目1即实现一个并发、io复用的守护进程时间服务器, 要求当客户端向服务器发送“ whafstime? ”字符串时,服务器回应当时的系统 时间字符串。现在要用守护进程实现一个时间服务器,呈现的功能是:服务器运行后自 动成为守护进程,返回shel 1;客户端运行后收到服务器发来的当前时间。从而 达到利用网络把时间资讯传递给用户的目的。要使服务器可以同时处理多个客户端的请求需要用到并发服务器,我们采 用I/O多路复用。详细过程如图2-1服务器端工作流程图所示。图2-1服务端工作流程图2.2守护进程的原理在Client/Server模式下,服务器监听(Listen)在一

4、个特定的端口上等待客 户连接。连接成功后服务器和客户端通过端口进行数据通信。守护进程的工作 就是打开一个端口,并且等待(Listen)进入连接。如果客户端产生一个连接请 求,守护进程就创建(Fork)一个子服务器响应这个连接,而主服务器继续监 听其他的服务请求。独立运行的守护进程由init脚本负责管理,所有独立运行的守护进程的脚 本在/etc/rc.d/init.d/目录下。系统服务都是独立运行的守护进程包括:syslogd和 cron等。运行独立的守护进程工作方式称作:stand-alone。它Unix传统的C/S 模式的访问模式。服务器监听(Listen)在一个特点的端口上等待客户端的联机

5、。 如果客户端产生一个连接请求,守护进程就创建(Fork) 一个子服务器响应这 个连接,而主服务器继续监听。以保持多个子服务器池等待下一个客户端请求。 工作在stand-alone模式下的网络服务有route、gated。另外是大家最熟悉是 Web服务器:Apache和邮件服务器Sendmail、域名服务器Bind。因为这些负载 很大服务器上,预先创子服务器,可以通过客户的服务速度。在Linux系统中 通过stand-alone工作模式启动的服务由/etc/rc.d/下面对应的运行级别当中的符 号链接启动。第三章设计实现31关键技术分析311创建守护进程在linux操作系统中在系统的引导的时候

6、会开启很多服务,这些服务就叫做 守护进程。守护进程是脱离于终端并且在后台运行的进程。守护进程脱离于终端是为了避 免进程在执行过程中的信息在任何终端上显示并且进程也不会被任何终端所产 生的终端信息所打断。守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程。它 是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或 等待处理某些发生的事件。守护进程常常在系统引导装入时启动,在系统关闭 时终止。由于在Linux中,每一个系统与用户进行交流的界面称为终端,每一个从 此终端开始运行的进程都会依附于这个终端,这个终端就称为这些进程的控制 终端,当控制终端被关闭时,相应的进

7、程都会自动关闭。但是守护进程却能够 突破这种限制,它从被执行开始运转,直到整个系统关闭时才退出。如果想让 某个进程不因为用户或终端或其他地变化而受到影响,那么就必须把这个进程 变成一个守护进程。创建一个守护进程如下图2-2守护进程:熙翩)创建新会话屮设直工作目录屮重设交件枫限掩码屮关闭文件描述符屮结束屮图2 2守护进程服务器流程图创建守护进程,要先创建子进程,然后再退出父进程。使用的是系统函数setsid在子进程中创建新会话,从而使进程完全独立出 来,从而摆脱其他进程的控制。 改变当前目录为根目录,利用chdir(“/”)更改。重设文件权限掩码,使新文件的权限位不受原文件模式创建掩码的权限位

8、的影响,使用函数umask()。 close()关闭文件描述符。同文件权限码一样,用fork函数新建的子进程会 从父进程那里继承一些已经打开了的文件。这些被打开的文件可能永远 不会被守护进程读写,但它们一样消耗系统资源,而且可能导致所在的文 件系统无法卸下,所以应该被关闭。3.1.2 I/O复用的select函数我们需要服务器具有这样的能力:如果一个或多个I/O条件满足(如输入 已准备好被读,或描述字可以承接更多的输出)时,就被通知到。这个能力被 称为I/O复用,详细过程如图2-3 I/O复用的过程。进程內核系统调用尿 1 敎 select 数据报未准备好进程阻塞于 select 调 E.I,

9、 等待慕个套 接口的一个 条件变齿可返回可读条件等特数据v数据报准备好函数* 拷贝数据报数据拷贝到进程期间阻塞处理数据报*图2-3 I/O复用的过程拷贝完戚将数据报从內 核拷贝到进程如果一个TCP服务器既要处理监听套接口,又要处理已连接套接口,一般 要用到I/O复用。select的功能可以用一句话来描述:实现基于I/O多路复用的异步并发编 程。当server要对外提供大量的client请求服务时,假如使用阻塞方式,在单 线程中,由于accept和recev都是阻塞式的,那么当一个client被服务器accept 后,它可能在send发送消息时阻塞,因此服务器就会阻塞在recev调用。即时 此时

10、有其他的client进行connect,也无法进行响应。而如果使用select,在服务器端先注册由socket创建的文件描述符,然后进入select调用。只有当由socket 创建的文件描述符的状态发生改变时,才执行accept操作,并把得到的client 的文件描述符进行注册,再次进入select调用。当select检查到有文件描述符的 状态改变时,如果是server的socket创建的文件描述符,则执行accept操作, 否则执行recev操作。当请求的client数目比较多时,select明显能够提高并发 性。313网络套接字函数面向连接的客户机/服务器程序工作模式,服务器进程首先用so

11、cket()建立 流套接字,在用bind()套接字与本地地址绑定,在用listen()侦听,即准备好接 受连接,在用accept。接收连接,然后等待客户进程连接请求的到来,在用recv() 接收数据,send()发送数据,最后用close()关闭套接字;客户端进程,首先用 socket()建立套接字,在用connect()将套接字与远程主机连接,在用send()发送 数据,recv()接收数据,最后用close()关闭套接字。如下图3-3面向连接的客户 /服务器程序工作模式描绘了网络套接字编程的过程。图3-3面向连接的客户/服务器程序工作模式3.2关键程序代码分析3.2.1创建守护进程 第一次

12、调用fork的目的是保证调用setsid的调用进程不是进程组长。(而 setsid函数是实现与控制终端脱离的唯一方法)。 setsid函数使进程成为新会话的会话头和进程组长,并与控制终端断开连 接。第二次调用fork的目的是:即使守护进程将来打开一个终端设备,也不会 自动获得控制终端。这样可以保证这次生成的进程不再是一个会话头。忽略SIGHUP信号的原因是,当第一次生成的子进程(会话头)终止时, 该会话中的所有进程(第二次生成的子进程)都会收到该信号。3.2.2套接字编程 bind()函数就是绑定函数,其作用是调用socket()函数产生的套接字分配一 个本地协议地址,建立地址与套接字的对应关

13、系。进程如果绑定了一个特 定的本地IP地址到它的套接字上,对于TCP客户端,这就是此套接字上发 送的IP数据包分配了源IP地址;对于TCP服务器端,这就限制了该套接 字只接受目的地址为IP的客户连接。 socket()创建TCP套接字,作为TCP通信的传输端点,函数中的family参 数指明协议族,type参数指明产生套接字的类型,protocol参数是协议标志, 一般在调用socket()函数时将其置为0。 listen()函数,在调用之后服务器的状态从CLOSED转换到了 LISTEN状态。 参数sokfd是要设置的描述符;backlog参数规定了请求队列中的最大连接 数,对队列中等待服务

14、请求的数目进行了限制。如果一个服务请求到来时, 输入队列已满,该套接字将拒绝连接请求。 accept()函数使服务器接受客户端的连接请求,它将完成队列中的对头条目 返回给进程,并产生一个新的套接字描述符,这个新生成的描述符称为“已 连接套接字”当已完成对列为空时,进程睡眠,直到有已完成的连接到达 时。 TCP客户端使用connect()函数来配置套接字,建立一个与TCP服务器的连 接,Connect()函数用于激发TCP的三次握手过程,建立与远程服务的连接, 对于TCP连接的状态,conect()导致客户端从 CLOSED状态转到了 SYN_SENT状态。若建立成功,也就是connect()调

15、用成功,状态会再变到 ESTABLISHED状态;若函数connect。调用失败,则套接字不能再使用, 必须关闭。如果想重新调用socket()函数,生成新的套接字。 bzero()中server要置零的数据的起始地址。从&servaddr指针所指的地址位 置开始,将sizeof(sevaddr)字节置为0,bzero无返回值,并且使用string.h头文件sizeof的结果等于对象或者类型所占的内存字节数。 sockaddr_in为IPv4套接字地址结构通常也称为“网际套接字地址结构” 名字为 sockaddr_in。 htons将一个无符号短整型(16位)的主机数值转换为网络字节顺序。 S

16、OCK_STREAM提供面向连接的稳定数据传输,即TCP协议。OCK_STREAM应用 在C语言socket编程中,在进行网络连接前,需要用socket函数向系统申请一个通信 端口。3.2.3 I/O复用的select函数 select()它允许进程指示内核等多个事件中的任意一个发生,并仅在一个或 多个事件发生或经过指定时间时唤醒进程。 listenfd参数是由socket()函数产生的套接字描述符,在调用accept()函数前, 已经调用listen()函数将此套接字变成了监听套接字。 cliaddr和len用来返回对方的套接字地址结构和对应的结构长度。3.2.4处理客户连接 connfd是

17、套接字描述符,对于服务器是accept()函数返回的已连接套接字描 述符,对客户端是调用socket()函数返回的套接字描述符。 buff是指向发送信息的数据缓冲区。 strlen(buff)指明传送数据的长度。 write ()发送成功后返回发送的字节数,失败返回-1。心得体会在本次网络程序设计课程设计中,我们小组选中的题目是“服务器端客户 端通信”即用守护进程创建一个时间服务器,实现客户端与服务器端的连接。当然,这个题目最重要的地方并不在于服务器端与客户端实现了通信,最 重要的是以守护进程的方式来实现并且要运用I/O复用。守护进程,能够突破 传统的进程创建与退出方式,不再是随着控制终端的打

18、开和关闭而创建和退出, 而是自己成为一个独立的部分,随着整个系统实行运转,不因用户或终端而受 到影响,这是以守护进程创建的服务器的最大的优点,而I/O复用要解决TCP 服务器既要处理监听端口又要处理以监听端口的问题。在刚开始确定了这个题目的时候,我们先调试了书上的代码,发现书上给 出的程序宏观上符合本次课程设计的概况要求,我们把代码分成若干块,以书 中的程序为基础删除和添加功能,在服务器端的程序中,在定义完一系列的头 文件后,先用一个函数创建守护进程,其次,编写带有select()函数的I/O复用 的并发TCP服务器实现接收客户端消息;在客户端程序中,首先,实现输入字 符串并且比较该字符串是否

19、同定义的“ whats time”相同,其次,实现同数据 端的连接收发数据。这样,整个代码看起来功能层次分明,也便于学习。因此,要完成一项任务,我们要从自己的实际出发,既不能局限于书本上 的知识,我们一定要站在自身的角度上,刻苦学习,悉心钻研,这样才能圆满 的完成任务。参考文献甘刚著.Linux/UNIX网络编程.北京:中国水利水电出版社,2008附录1程序界面截图我们在Linux环境下使用C语言完成了“客户端和服务器端的通信”实现了一个并发 I/O复用的守护进程时间服务器。实现结果如下图:rootlccaLhcst:*-/haha文件编辑查看终端标签帮助 | rooLlocalhost ha

20、ha .- gcc server.c -o server | rooLlocalhost haha .- ./server| rooLlocal host ha ha .-rootrocafhost/haha文件 编辑)查看终端CD 标签帮助 roolLical host ha ha . = -gee c 1 ienL 1 .c -o c 1 ienL roolLical host ha ha .= ./c.ieni.what s Li meSat Feb 18 08:4S:44 2012图附录1-1程序运行效果截图附录2源代码服务器:#include vstdio.h#include vst

21、dlib.h#include #include verrno.h#include vnetinet/in.h#include vsys/socket.h#include vsys/select.h#include vunistd.h#include vsys/types.h#include vtime.h#define IPADDRESS127.0.0.1#define PORT1234#define BUFFMAX1024#define BACKLOG5#includevsyslog.h#includevsignal.h#include#define MAXFD 64/*定义守护进程函数*/

22、void daemon_init(const char *pname,int facility)int i;pid_t pid;/*为避免挂起控制终端将Daemon放入后台执行*/if (pid=fork()!=0)exit(O); 是父进程,结束父进程,子进程继续/*脱离控制终端,登录会话和进程组*/setsid(); /使进程成为会话组长由于会话过程对控制终端的独占性,进程同时与控制终端脱离。/*处理SIGCHLD信号*/ signal(SIGHUP,SIG_IGN);如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统 资源。如果父进程等待子进程结束,将增加父进程

23、的负担,影响服务器进程的并发性 能。/*禁止进程重新打开控制终端*/if(pid=fork()!=0)exit(0);/*第一个子进程终止*/*将工作目录改变到根目录*/chdir(/);/*清除文件模式创建掩码*/umask(O);/*关闭所有打开的文件描述字*/for(i=0;ivMAXFD;i+)close(i);/*用syslogd处理错误*/ openlog(pname,LOG_PID,facility);/end daemon_init声明I/O多路复用select函数static void select_(int listenfd);声明处理客户端函数static void de

24、al_date(int *connfds,int num,fd_set *prset,fd_set *pallset);主函数int main(int argc,char *argv)/struct sockaddr_in cliaddr;/IPv4套接字地址结构通常也称为“网际套接字地址结构” 名字为 sockaddr_in。socklen_t cliaddrlen;/unsigned int/*调用守护进程函数*/daemon_init(argv0,0);/*生成TCP套接字*/int sockfd;if(sockfd = socket(AF_INET,SOCK_STREAM,0)=-l)

25、;/IPv 4 协议,字节流套接口/*对服务器的结构初始化并赋值*/struct sockaddr_in server;bzero (&server,sizeof(server);server.sin_family = AF_INET;inet_pton(AF_INET,IPADDRESS, &server.sin_addr);server.sin_addr.s_addr = htonl(INADDR_ANY);server.sin_port = htons(PORT);/*将描述符sockfd与server套接字地址结构中的协议地址绑定*/ if (bind(sockfd,(struct s

26、ockaddr*)&server,sizeof(server) = -1);/*转换为被动套接字*/listen(sockfd,BACKLOG);/*I/O 复用 */select_(sockfd);return 0;/end main/I/O复用static void select_(int listenfd)int connfd,sockfd;struct sockaddr_in cliaddr;socklen_t cliaddrlen;fd_set rset,allset;int maxfd,maxi;int nready;/定义描述符个数/*初始化客户连接描述符*/int i;int

27、clientsFD_SETSIZE;for (i = 0;i FD_SETSIZE;i+) clientsi = -1;/*初始化 allset*/FD_ZERO(&allset);/*设置 listenfd 为 1*/FD_SET(listenfd,&allset);maxfd = listenfd;maxi = -1;while(1)死循环rset = allset;/*获取可用描述符的个数*/nready = select(maxfd+1, &rset,NULL,NULL,NULL);/描述字个数,读/*测试监听描述符是否准备好*/if (FD_ISSET(listenfd,& rset

28、)cliaddrlen = sizeof(cliaddr);/*接受客户端连接请求*/if (connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&cliaddrlen) = -1);/*将新的连接描述符添加到客户端数组中*/for (i = 0;i FD_SETSIZE;i+)if (clientsi maxfd ? connfd : maxfd);/取 最大值 maxi = (i maxi ? i : maxi);/取最大值if (-nready = 0)continue;/没有可读描述符/*调用处理客户连接函数*/deal_date(c

29、lients,maxi, &rset,&allset);/end while/end select_处理客户连接static void deal_date(int *connfds,int num,fd_set *prset,fd_set *pallset) int i,n;char buffBUFFMAX;数据缓存区 memset(buff,O,BUFFMAX);/将 buff 数组都赋值为 0 time_t ticks;/*检查所有客户端数据*/for (i = 0;i = num;i+)if (connfdsi #include vsys/socket.h#include #includ

30、e #include vstdlib.h #include vunistd.h#include vsys/types.h#define BUFFMAX1024#define IPADDRESS127.0.0.1#define SERV_PORT1234主函数int main(int argc,char *argv)int sockfd;struct sockaddr_in server;/*生成TCP套接字*/sockfd = socket(AF_INET,SOCK_STREAM,0);/IPv4 协议,字节流套接口/*对服务器的结构初始化并赋值*/bzero (&server,sizeof(

31、server);server.sin_family = AF_INET;server.sin_port = htons(SERV_PORT);inet_pton(AF_INET,IPADDRESS, &server.sin_addr);server.sin_addr.s_addr = htonl(INADDR_ANY);/*连接服务器端*/connect(sockfd,(struct sockaddr* )&server,sizeof(server);/*发送数据*/char buffBUFFMAX;char *str = whatstime;while(l)scanf(”s,buff);if(strcmp(str,buff) = 0) send(sockfd,buff,strlen(buff),0);/写入 recv(sockfd,buff,BUFFMAX,0);/读取 printf(%s,buff);close(sockfd);return 0;

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!