《《网络编程》复习题.pdf》由会员分享,可在线阅读,更多相关《《网络编程》复习题.pdf(40页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、1网络应用的标准模型是()模型。随着Internet技术的兴起,B/S模型是对C/S模型的一种()或者()。2.C/S与B/S模式主要区别包括:()、()、()、()、()等方面。3.标识一条 TCP 连接的 4 个信息为:()、()、()、()。4.Linux 支持多种套接字类型,即应用程序希望的通信服务类型,如:()、()、()。5.监听套接字是基本 socket 函数()的返回值,连接套接字是基本 socket 函数()的返回值。6.高级 socket 函数:int send(int sockfd,void buf,int len,int flags),当 flags=0,相当于基本 s
2、ocket函数中的()函数。当 flags=MSG_OOB,表示()。7.高级 socket 函数:int recvfrom(int sockfd,void*buf,int len,unsigned char flags,struct socketaddr*from,socklen_t*addrlen),用于()。8.创建原始套接字时,socket 函数的三个参数分别是()、()和()。9.有些流行的网络应用程序适合用基于 IP 的原始套接字实现,如:()。10.系统创建新进程,并为该子进程准备()段、()段和()段。11.子进程终止时,如果父进程存在且未处理()信号,则()变为僵尸进程。12
3、.有父子等亲缘关系的进程间通信方法,可采用()、()。13.TCP 发送多字节带外数据:send(sockfd,”EDF”,3,MSG_OOB);则()被系统认定为“带外数据”。14.多进程 TCP 并发服务器模型有:()、()、()、()。1简述循环/迭代、并发服务器及其特点。2请画出基于 TCP 套接字的网络编程模型框架图。3请写出两组常用的字节排序函数,并说明其含意。4.请写出简单的基于 UDP 套接字的服务器端网络程序模板。5.请写出 socket 选项:SO_REUSEADDR 的作用和使用方法。6.请简述多路复用 I/O 模型的原理。7.请画出 inetd 守护进程的工作流程图。8
4、.请写出简单的基于 UDP 套接字的客户端网络程序模板。1 编程产生子进程、孙进程(即子进程的子进程),并使进程按“孙-子-父”的顺序结束,要求清除所有僵尸进程。2.编程实现如下 TCP 多进程网络程序:(1)服务器等待接收客户的连接请求,一旦连接成功则显示客户地址,接着接收客户端的名称并显示;然后接收来自该客户的字符串,每当收到一个字符串时,显示该字符串,并将字符串按照恺撒密码的加密方式(K=3)进行加密,再将加密后的字符发回客户端;之后,继续等待接收该客户的信息,直到客户关闭连接。要求服务器具有同时处理多个客户请求的能力。(2)客户首先与相应的服务器建立连接;接着接收用户输入的客户端名称,
5、并将其发送给服务器;然后继续接收用户输入的字符串,再将字符串发送给服务器,同时接收服务器发回的加密后的字符串并显示。之后,继续等待用户输入字符串,直到用户输入 Ctrl+D,客户关闭连接并退出。1C/S 变化 改进 2.硬件环境不同、安全要求不同、程序架构不同、软件重用不同、系统维护不同 3本地 IP 本地端口 对方 IP 对方端口 4.SOCKET_STREAM SOCKET_DGRAM SOCKET_RAW 5socket()accept()6.write()发送带外数据 7.接收 UDP 数据包 8.AF_INET SOCK_RAW PPROTO_ICMP/IGMP/IP 9.ping
6、程序 10.数据 堆栈 代码 11.SIGCHLD 子进程 12.管道(pipe)非命名 UNIX 域 socket(socketpair)13.F 14.一个子进程对应一个客户端 延迟创建子进程 预创建子进程 多路复用 I/O 1循环服务器 任一时刻只处理一个客户机请求,处理请求过程中下一请求等待(1 分)节省服务器资源,响应时间长,适合处理非耗时请求(2 分)并发服务器 并发执行,每收到一个连接请求创建一个进程处理该连接,服务器继续等待下一连接(1 分)响应速度快,占用系统资源多(2 分)2下图,一行一分 3#include uint16_t htons(uint16_t hostshor
7、t)uint32_t htonl(uint32_t hostlong)均返回:网络字节序值(1 分)uint16_t ntohs(uint16_t netshort)uint32_t ntohl(uint32_t netlong)均返回:主机字节序值(1 分)h:主机 n:网络 s:短整数(端口号)l:长整数(IP 地址)(各 1 分)4.#include#include#inlcude int main(void)int socketfd;(1 分)if(sockfd=socket(AF_INET,SOCK_DGRAM,0)=-1)(2 分)perror(“Create socket fai
8、led.”);exit(1);/*Bind socket to address*/(1 分)loop (1 分)/*recvfrom:receive and process data from client*/*sendto:send resuts to client*/close(sockfd);(1 分)5.作用:快速重启服务器程序(2 分)启动服务器程序的多个实例(绑定本地 IP 地址的多个别名)(2 分)使用方法:int opt=SO_REUSEADDR/1;(1 分)setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt
9、);(1 分)6.int select(int maxfd,fd_set*rdset,fd_set*wrest,fd_set*exset,struct timeval*timeout);(2 分)select 函数检查侦听 socket 是否有连接到达、已连接 socket 是否有数据到达、已连接 socket是否可以写数据。(2 分)在测试是否可读的描述符集合 rdset 中同时包含侦听 socket 和已连接 socket,在测试是否可写描述符集合中包含已连接 socket,就可以实现多路复用。(2 分)7.每行 1 分 8.#include#include#inlcude int mai
10、n(void)int sockfd;(1 分)if(sockfd=socket(AF_INET,SOCK_DGRAM,0)=-1)(2 分)perror(“Create socket failed.”);exit(1);/*sendto:send data to the server*/(1 分)/*recvfrom:receive data from the server*/(1 分)close(sockfd);(1 分)1 Int son_pid;Int grandson_pid;(1 分)If(son_pid=fork()=0)(1 分)/儿进程(1 分)If(grandson_pid=
11、fork()=0)(1 分)/孙进程(1 分)exit();(1 分)else(1 分)/儿进程(1 分)wait();(1 分)exit();(1 分)else /父进程 wait();exit();(1 分)2.服务器端 include#include#include#include#include#include#include#include#define PORT 1546#define BACKLOG 5#define MAXDATASIZE 1024 void caesar(char*str);void process_client(int connfd,struct socka
12、ddr_in client);int main()int listenfd,connfd;pid_t pid;struct sockaddr_in server,client;socklen_t len;(2分)if(listenfd=socket(AF_INET,SOCK_STREAM,0)=-1)perror(Create socked faild.n);exit(1);int opt=SO_REUSEADDR;setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt);bzero(&server,sizeof(server);
13、server.sin_family=AF_INET;server.sin_addr.s_addr=htonl(INADDR_ANY);server.sin_port=htons(PORT);if(bind(listenfd,(struct sockaddr*)&server,sizeof(server)=-1)perror(bind()error.n);exit(1);if(listen(listenfd,BACKLOG)=-1)perror(listen()error.n);exit(1);len=sizeof(client);while(1)if(connfd=accept(listenf
14、d,(struct sockaddr*)&client,&len)=-1)perror(accept()error.n);exit(1);(3分)if(pid=fork()0)close(connfd);continue;else if(pid=0)close(listenfd);process_client(connfd,client);else perror(fork()error.n);exit(1);close(listenfd);return 0;(1分)void caesar(char*str)while(*str)if(*str=a&*str=A&*strz&*strZ&*str
15、0)recvbufnum=0;printf(Received client(%s)message:%s,client_name,recvbuf);bcopy(recvbuf,sendbuf,num+1);caesar(sendbuf);send(connfd,sendbuf,strlen(sendbuf),0);客户端#include#include#include#include#include#include#include#include#define PORT 1546#define MAXDATASIZE 1024 void process(FILE*fp,int sockfd);c
16、har*getMessage(char*sendline,int len,FILE*fp);int main(int argc,char*argv)int sockfd;struct hostent*he;struct sockaddr_in server;if(argc!=2)printf(USAGE:%s n,argv0);exit(1);(1分)if(he=gethostbyname(argv1)=NULL)perror(gethostbyname()error.n);exit(1);(1分)if(sockfd=socket(AF_INET,SOCK_STREAM,0)=-1)perro
17、r(socket()error.n);exit(1);(1分)bzero(&server,sizeof(server);server.sin_family=AF_INET;server.sin_port=htons(PORT);server.sin_addr=*(struct in_addr*)he-h_addr);(1分)if(connect(sockfd,(struct sockaddr*)&server,sizeof(server)=-1)perror(connect()error.n);exit(1);process(stdin,sockfd);close(sockfd);return
18、 0;void process(FILE*fp,int sockfd)char sendlineMAXDATASIZE+1;char recvlineMAXDATASIZE+1;int num;printf(connected to server.n);printf(Input clients name:);if(fgets(sendline,MAXDATASIZE,fp)=NULL)printf(nExit.n);return;send(sockfd,sendline,strlen(sendline),0);while(getMessage(sendline,MAXDATASIZE,fp)!
19、=NULL)send(sockfd,sendline,strlen(sendline),0);if(num=recv(sockfd,recvline,MAXDATASIZE,0)=0)printf(Server terminated.n);return;recvlinenum=0;printf(server Message:%s,recvline);printf(nExit.n);char*getMessage(char*sendline,int len,FILE*fp)printf(Input string to server:);return(fgets(sendline,len,fp);
20、(1分)1.C/S模式的网络编程包括通信()和()端的设计,重点在于通信()端的设计。B/S模型的特点是:“瘦()端、胖()端”。2.C/S模型是非对称模型,主要体现在()和()上。3.socket 套接字是位于 TCP/IP 4 层协议的()层和()层之间的应用程序接口(API)。它支持多种通信协议,如()、()、()。4.Linux 支持多种套接字类型,即应用程序希望的通信服务类型,如:()、()、()。5.基本 socket 函数:socke()和 accept()的返回值应分别赋值给()和()套接字文件描述符。6.高级 socket 函数:int recv(int sockfd,voi
21、d buf,int len,int flags),当 flags=0,相当于基本 socket函数中的()函数。当 flags=MSG_OOB,表示()。7.高级 socket 函数:int sendto(int sockfd,const void*buf,int len,unsigned char flags,struct socketaddr*to,int tolen),用于()。8.有些流行的网络应用程序适合用基于UDP的网络编程实现,如:()、()、()。9.创建原始套接字时,要求用户权限为()。10.父、子进程共享()段,而父进程的()段和()段被复制(copy-on-write)给
22、子进程。11.系统调用()终止子进程,并向父进程发送()信号。12.无父子等亲缘关系的进程间通信方法,可采用()、()。13.TCP 支持()字节的带外数据。14.Linux 系统主要实现了四种输入/输出(I/O)模型,即()、()、()和()。1简述有连接网络程序的执行过程。2请写出简单的基于 TCP 套接字的服务器端网络程序模板。3网络编程时,为什么要考虑字节顺序问题?4.请画出基于 UDP 套接字的网络编程模型框架图。5.请简述 shutdown 和 close 的区别。6.请简述多路复用 I/O 模型的服务器处理过程。7.简述将用户进程转换为守护进程的步骤。8.请写出简单的基于 TCP
23、 套接字的客户端网络程序模板。1.编程实现调用 fork 两次,使孙子进程成为孤儿进程,由 init 进程管理(“领养”)从而清除僵尸进程的方法。2.编程实现如下 TCP 多进程网络程序:(1)服务器等待接收客户的连接请求,一旦连接成功则向客户发送欢迎信息,接着接收客户端的名称并显示;然后接收来自该客户的字符串,将该符串反转,并将结果送回客户。要求服务器具有同时处理多个客户请求的能力。(2)客户首先与相应的服务器建立连接;接着接收用户输入的客户端名称,并将其发送给服务器;然后继续接收用户输入的字符串,再将字符串发送给服务器,同时接收服务器发回的反转字符串并显示。之后,继续等待用户输入字符串,直
24、到用户输入 Ctrl+D,客户关闭连接并退出。1客户 服务器 服务器 客户 服务器 2.软件结构 工作过程 3应用 传输 Unix INET INET6 4.SOCKET_STREAM SOCKET_DGRAM SOCKET_RAW 5.监/侦听套接字 连接套接字 6.read()接收带外数据 7.发送 UDP 数据包 8.DNS/域名系统 NFS/网络文件系统 SNMP/简单网络管理协议 或 即时通信/IP 电话/实时视频 9.超级/root 用户 10.代码 数据 堆栈 11.exit SIGCHLD 12.命名管道 命名 UNIX 域 socket 13.1 14.阻塞式 I/O 模型默
25、认 I/O 模型 非阻塞式 I/O 模型 多路复用 I/O 模型 信号驱动 I/O 模型 1服务程序启动(1 分)客户程序启动(1 分)客户端与服务器建立连接(1 分)客户端发送请求(1 分)服务器处理请求,返回响应(1 分)服务器断开连接,等待下一个请求(1 分)2./*include some header files*/int main(void)int sockfd,connect_sock;if(sockfd=socket(AF_INET,SOCK_STREAM,0)=-1)(1 分)perror(“create socket failed.”);exit(-1);/*bind so
26、ckfd to some address*/(1 分)/*listen*/(1 分)loop (1 分)if(connect_sock=accept(sockfd,NULL,NULL)=-1)(1 分)perror(“Accept error.”);exit(-1);/*read and process request*/close(connect_sock);close(sockfd);(1 分)3不同机器表示数据的字节顺序是不同的,为保证”大端“和”小端“字节序的机器之间能相互通信,需在发送多字节整数时,将主机字节序转换成网络字节序,或反之。(答出这即可,答下面也可)Intel 芯片:低字
27、节在前,高字节在后,称 little-endian;RISC 芯片:高字节在前,低字节在后,称 big-endian,4.前两行各 1 分,后两行各 2 分 5.shutdown 操作连接通道,其他进程不能再使用已被关闭的通道;close 操作描述符,其他进程仍然可以使用该 socket 描述符。(3 分)close 关闭应用程序进程与 socket 的接口,调用 close 之后该应用程序进程不能再读写这个socket;shutdown 可以只关闭一个通道,另一个通道仍然可以操作。(3 分)6.设置读和写描述符集合,其中读描述符集合包括侦听 socket(1 分)调用 select 测试 s
28、ocket 描述符是否就绪(1 分)侦听 socket 就绪则接收新连接(1 分)其他 socket 就绪则执行读写操作(1 分)重复步骤 14(1 分)要求将所有 socket 描述符设置为非阻塞方式(1 分)7.调用 fork,然后父进程退出,子进程继续运行。(0.5 分)调用 setsid 创建新的 session,成为头进程。(0.5 分)忽略信号 SIGHUP,再次调用 fork,然后父进程(session 的头进程)退出。(1 分)调用函数 chdir(“/”),使进程不使用任何目录(1 分)调用函数 unmask(0),使进程对任何写的内容有权限(1 分)关闭所有打开的文件描述符
29、(0.5 分)为标准输入(0),标准输出(1),标准错误输出(2)打开新的文件描述符 (0.5 分)处理信号 SIGCLD,避免守护进程的子进程成为僵尸进程(1 分)8./*include some header files*/(1 分)int main(void)int sockfd;(1 分)if(sockfd=socket(AF_INET,SOCK_STREAM,0)=-1)(1 分)perror(“Create socket failed.”);exit(-1);/*connect to server*/(1 分)/*send requst and receive response*/
30、(1 分)close(sockfd);(1 分)int main()int i;pid_t pid;(1分)pid=fork();(1分)if(pid=0)(2分)/子进程1 coutfirst child proc:getpid()endl;for(i=0;i5;i+)if(fork()=0)(2分)/子进程2,3,4,5,6 coutchild getpid()endl;sleep(1);exit(0);(2分)exit(0);(1分)for(;)(2分)2.服务器端:#include#include#include#include#include#include#include#incl
31、ude#include#define PORT 1234#define BACKLOG 2#define MAXCHARSIZE 1000 void process_client(int connectfd,struct sockaddr_in client);int main(void)int listenfd,connectfd;struct sockaddr_in server,client;int sin_size;int opt=SO_REUSEADDR;pid_t pid;(2分)if(listenfd=socket(AF_INET,SOCK_STREAM,0)=-1)perror
32、(Create socket failed.);exit(-1);setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt);bzero(&server,sizeof(server);server.sin_family=AF_INET;server.sin_port=htons(PORT);server.sin_addr.s_addr=htonl(INADDR_ANY);if(bind(listenfd,(struct sockaddr*)&server,sizeof(struct sockaddr)=-1)perror(Bind
33、error.);exit(-1);if(listen(listenfd,BACKLOG)=-1)perror(listen error.);exit(-1);sin_size=sizeof(struct sockaddr_in);while(1)if(connectfd=accept(listenfd,(struct sockaddr*)&client,&sin_size)=-1)perror(Accept error.);exit(-1);(3分)if(pid=fork()0)close(connectfd);continue;else if(pid=0)close(listenfd);pr
34、ocess_client(connectfd,client);exit(1);else perror(Fork error.n);exit(0);close(listenfd);(1分)void process_client(int connectfd,struct sockaddr_in client)char recvbufMAXCHARSIZE;char sendbufMAXCHARSIZE;char client_nameMAXCHARSIZE;int recvlen,i;printf(You get a connection from%sn,inet_ntoa(client.sin_
35、addr);send(connectfd,Welcome to my server.n,22,0);recvlen=recv(connectfd,client_name,MAXCHARSIZE,0);if(recvlen=0)close(connectfd);printf(Client disconnected.n);return;else if(recvlen0)close(connectfd);printf(Connect broked.n);return;client_namerecvlen=0;printf(Client name is%s.n,client_name);while(r
36、ecvlen=recv(connectfd,recvbuf,MAXCHARSIZE,0)recvbufrecvlen=0;printf(Receive from client message:%sn,client_name,recvbuf);for(i=0;irecvlen;i+)sendbufi=recvbufrecvlen-i-1;sendbufrecvlen=0;send(connectfd,sendbuf,strlen(sendbuf),0);printf(Client:%s disconnected.n,client_name);close(connectfd);客户端:#inclu
37、de#include#include#include#include#include#include#define PORT 1234#define MAXDATASIZE 1000 int main(int argc,char*argv)int fd,numbytes;char bufMAXDATASIZE;struct hostent*he;struct sockaddr_in server;int i=1;if(argc!=2)printf(Usage:%s n,argv0);exit(-1);(1分)if(he=gethostbyname(argv1)=NULL)perror(geth
38、ostbyname error.);exit(-1);(1分)if(fd=socket(AF_INET,SOCK_STREAM,0)=-1)perror(Create socket failed);exit(1);(1分)bzero(&server,sizeof(server);server.sin_family=AF_INET;server.sin_port=htons(PORT);server.sin_addr=*(struct in_addr*)he-h_addr);(1分)if(connect(fd,(struct sockaddr*)&server,sizeof(struct soc
39、kaddr)=-1)perror(Bind error.);exit(1);if(numbytes=recv(fd,buf,MAXDATASIZE,0)=-1)perror(recv error.);exit(1);bufnumbytes=0;printf(Server Message:%sn,buf);printf(Input your name:);scanf(%s,buf);if(numbytes=send(fd,buf,strlen(buf),0)=-1)perror(Send error.);exit(1);(1分)while(i)printf(Input message(max c
40、har:%d):,MAXDATASIZE);scanf(%s,buf);if(strlen(buf)0)(1分)close(connectfd);(1分)continue;(1分)else if(pid=0)(1分)close(listenfd);(1分)process_client(connectfd,client);exit(1);(1分)6.图 1 分,每个实现步骤要点各 1 分 1)服务器建立 socket,并创建一定数量子进程 2)服务器父进程维护所有子进程的状态表,父进程和子进程通过管道通信 3)子进程接收连接时给父进程发 1,关闭连接时发 0 4)父进程收到 1 时检查空闲子进程
41、数目是否小于下限,小于下限则创建新的子进程 5)父进程收到 0 时检查空闲子进程数目是否大于上限,大于上限则终止一些子进程 7.设置读和写描述符集合,其中读描述符集合包括侦听 socket(1 分)调用 select 测试 socket 描述符是否就绪(1 分)侦听 socket 就绪则接收新连接(1 分)其他 socket 就绪则执行读写操作(1 分)重复步骤 14(1 分)要求将所有 socket 描述符设置为非阻塞方式(1 分)1.#include#include#include#include#include#include using namespace std;void sigch
42、ld_handler(int);int main()struct sigaction act;(1分)int i;act.sa_handler=sigchld_handler;(2分)act.sa_flags=0;sigemptyset(&act.sa_mask);if(sigaction(SIGCHLD,&act,NULL)0)(2分)coutsigaction error.endl;exit(1);for(i=0;i3;i+)if(fork()=0)(2分)coutchild getpid()0;)(2分)coutchild piddied:WEXITSTATUS(stat)endl;2.
43、服务器端:#include#include#include#include#include#include#include#include#include#define PORT 1234#define BACKLOG 2#define MAXCHARSIZE 1000 int main(void)int listenfd,connectfd;struct sockaddr_in server,client;int sin_size;int opt=SO_REUSEADDR;pid_t pid;(1分)if(listenfd=socket(AF_INET,SOCK_STREAM,0)=-1)p
44、error(Create socket failed.);exit(-1);setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt);bzero(&server,sizeof(server);server.sin_family=AF_INET;server.sin_port=htons(PORT);server.sin_addr.s_addr=htonl(INADDR_ANY);(1分)if(bind(listenfd,(struct sockaddr*)&server,sizeof(struct sockaddr)=-1)per
45、ror(Bind error.);exit(-1);(1分)if(listen(listenfd,BACKLOG)=-1)perror(listen error.);exit(-1);sin_size=sizeof(struct sockaddr_in);while(1)if(connectfd=accept(listenfd,(struct sockaddr*)&client,&sin_size)=-1)perror(Accept error.);exit(-1);(3分)if(pid=fork()0)close(connectfd);continue;else if(pid=0)close
46、(listenfd);process_client(connectfd,client);exit(1);else perror(Fork error.n);exit(0);close(listenfd);(2分)void process_client(int connectfd,struct sockaddr_in client)char recvbufMAXCHARSIZE;char sendbufMAXCHARSIZE;char client_nameMAXCHARSIZE;int recvlen,i;printf(You get a connection from%sn,inet_nto
47、a(client.sin_addr);send(connectfd,Welcome to my server.n,22,0);recvlen=recv(connectfd,client_name,MAXCHARSIZE,0);if(recvlen=0)close(connectfd);printf(Client disconnected.n);return;else if(recvlen0)close(connectfd);printf(Connect broked.n);return;client_namerecvlen=0;printf(Client name is%s.n,client_
48、name);while(recvlen=recv(connectfd,recvbuf,MAXCHARSIZE,0)recvbufrecvlen=0;printf(Receive from client message:%sn,client_name,recvbuf);send(connectfd,recvbuf,strlen(sendbuf),0);printf(Client:%s disconnected.n,client_name);close(connectfd);客户端:#include#include#include#include#include#include#include#d
49、efine PORT 1234#define MAXDATASIZE 1000 int main(int argc,char*argv)int fd,numbytes;char bufMAXDATASIZE;struct hostent*he;struct sockaddr_in server;int i=1;if(argc!=2)printf(Usage:%s n,argv0);exit(-1);(1分)if(he=gethostbyname(argv1)=NULL)perror(gethostbyname error.);exit(-1);(1分)if(fd=socket(AF_INET,
50、SOCK_STREAM,0)=-1)perror(Create socket failed);exit(1);(1分)bzero(&server,sizeof(server);server.sin_family=AF_INET;server.sin_port=htons(PORT);server.sin_addr=*(struct in_addr*)he-h_addr);(1分)if(connect(fd,(struct sockaddr*)&server,sizeof(struct sockaddr)=-1)perror(Bind error.);exit(1);if(numbytes=re