logo资料库

2017 19年网络程序设计.pdf

第1页 / 共11页
第2页 / 共11页
第3页 / 共11页
第4页 / 共11页
第5页 / 共11页
第6页 / 共11页
第7页 / 共11页
第8页 / 共11页
资料共11页,剩余部分请下载后查看
线 订 装 线 订 装 西 安 电 子 科 技 大 学 考试时间 120 分钟 试 题 题号 一 二 三 四 五 六 总分 分数 1.考试形式:闭卷  开卷□ ;2.本试卷共六大题,满分 100 分; 3.考试日期: 年 月 日;(答题内容请写在装订线外) 说明: 1.每道题在答题时分为二个部分:1)问题分析和方案设计;2)编程。 2.网络层协议使用 ipv4。 3.为减少手写代码量: 1)不用写头文件,bind()、connect()、accept()函数不用写参数; 2)不用考虑出现中断(EINTR)的情况,也不用考虑 read()返回值为 0 的情况; 3)给 sockaddr 或 sockaddr_in 填写内容时,可用 SET_ADDR_PORT(单播) 或 SET_ADDR_PORT_255(广播)代替;从磁盘上读取文件可用 int len=READ_FILE(char* buf)代替,其中 len 是文件长度,buf 起 始的数组存放文件内容;计算“和校验”可用 CHECK_SUM 代替; 4)重复的代码块,在第一次出现时可用方框把代码框住并在右边标记①、 ②等序号,下次出现时直接画方框并在内部加上标记即可; 5)可能用到的结构: : 师 教 课 任 : 号 学 : 名 姓 : 级 班 线 订 装 第1页 共 页 ip头部结构:struct iphdr {#if defined(__LITTLE_ENDIAN_BITFIELD) __u8 ihl:4, version:4; #elif defined (__BIG_ENDIAN_BITFIELD) __u8 version:4, ihl:4;#endif __u8 tos;/*服务类型*/ __u16 tot_len;/*数据包总长*/ __u16 id;/*标识*/ __u16 frag_off;/*标识位和碎片偏移*/ __u8 ttl;/* time to live*/ __u8 protocol;/*协议:TCP、UDP、ICMP等*/ __u16 check;/*首部校验和*/ __u32 saddr;/*源IP地址*/ __u32 daddr;/*目的IP地址*/};icmp头部结构: struct icmphdr { __u8 type; __u8 code; __u16 checksum; union { struct { __u16 id; __u16 sequence; } echo; __u32 gateway; struct { __u16 __unused; __u16 mtu; } frag; } un;};
一、在一个大楼顶端装有一台摄像机,网上的用户可以控制该摄像机, 来观赏周边风景,每个用户每次控制的时间不能超过 2 分钟,且不允 许多人同时控制该摄像机。请设计和实现控制该摄像机的服务器程序, 控制过程可用 CONTROL_CAMERA 表示。(20 分) 1) 问题分析和方案设计 每次只能一个人控制摄像机,因此不需要创建多个子进程;每次控制时间 不 能 超 过 2 分 钟 , 需 要 进 行 超 时 控 制 , 超 时 发 生 时 需 要 结 束 当 前 的 CONTROL_CAMERA。所以设计如下:选择 TCP 协议工作,父进程监听,当有客户 机连接成功,则创建一个子进程,父进程等待子进程结束,再去监听;子进程 设置 2 分钟超时,然后执行 CONTROL_CAMERA,发生超时则子进程退出。 2) 编程 void sigalarm_handler(int sig) { exit(0); } main() { int sock,connfd; struct sockaddr_in addr; struct sigaction sigact; sigact.sa_handler=sigalarm_handler; sigact.sa_mask=0; sigact.sa_flags=0; sigaction(SIGALRM,&sigact,NULL); if ((sock = socket(AF_INET,SOCK_STREAM,0)) < 0 ) exit(1); SET_ADDR_PORT; if ( bind() < 0 ) exit(1); if ((listen(sock,5) < 0 ) exit(1); for (;;) { connfd = accept(); if(connfd<0) 第2页 共 页
exit(1); if ( fork() == 0 ) { } close(sock); alarm(120); CONTROL_CAMERA; exit(0); close(connfd); wait(null); } close(sock); } 二、选择适当的 I/O 模型或服务器模型,在局域网内设计一个聊天程 序。任何一个用户都可以从本方终端上读入字串,发送给对方,并在 对方的终端上显示出来。 (提示: 一方可以多次给对方发数据,而不需要对方响应)(15 分) 1) 问题分析和方案设计 本题需要套接字接收和发送能够同时工作,而不会发生收、发过程互相阻 塞。所以设计如下:选择 TCP 协议工作,创建一个子进程。父进程监听,当有 客户机连接成功,从连接套接字接收数据并显示;子进程则从控制台上读入字 串,然后用主动套接字去与对方连接,发送数据给对方。 2) 编程 void sigchild_handler(int sig) { wait(NULL); } main() { int sock,connfd,sock2; struct sockaddr_in addr; string str; struct sigaction sigact; sigact.sa_handler=sigchild_handler; sigact.sa_mask=0; 第3页 共 页
sigact.sa_flags=0; sigaction(SIGCHLD,&sigact,NULL); if ( fork() == 0 ) for(;;) { cin>>str; if ((sock2 = socket(AF_INET,SOCK_STREAM,0)) < 0 ) exit(1); SET_ADDR_PORT; if(connect()<0) exit(1); cin>>str; write(sock2,str.c_str(),sizeof(str)); close(sock2); } exit(0); { } if ((sock = socket(AF_INET,SOCK_STREAM,0)) < 0 ) exit(1); SET_ADDR_PORT; if ( bind() < 0 ) exit(1); if ((listen(sock,5) < 0 ) exit(1); for (;;) { connfd = accept(); if(connfd<0) exit(1); char ch[1024]; int n=read(connfd,ch,1024); close(connfd); string str(ch); cout<
三、在一个公园中有 10 万只景观灯,这 些灯只有亮、灭两种状态,并处于同一个 局域网内。请设计和实现一个程序,可以控制这些灯实现任意的亮、 灭状态组合。(20 分) 1) 问题分析和方案设计 本题如采用 tcp 协议,则每轮控制需要 10 万次数据交互,难以满足实时性。 所以设计如下:选择 UDP 协议工作,将指令广播给所有灯;每个灯设置唯一编 号从 0~99999,用 UDP 有效数据的每一位代表一盏灯的亮、灭状态,每个灯依据 编号取出状态位,根据状态位打开或关闭。运行策略存放于磁盘文件上。 2) 编程 main() { int sock; struct sockaddr_in addr; string str; if ((sock = socket(AF_INET,SOCK_DGRAM,0)) < 0 ) exit(1); SET_ADDR_PORT_255; for (;;) { } int len=READ_FILE(char* buf); int n=send(sock,buf,len); sleep(1); close(sock); } 四、在 Internet 网上有 100 个主机,这些主机均可响应常用的网络调 试指令,并且其 IP 地址已知。请使用套接字实现一个程序,每隔 30 分钟测试一遍这些域名对应的主机是否能够连通。(15 分) 1) 问题分析和方案设计 本题要测试各主机的连通性,从网络层进行测试即可,而不必关心传输层 使用哪种协议。所以设计如下:选择原始套接字工作,将 ICMP 请求回显指令发 给各个主机,等待主机回复,并计算各个主机的响应时间。 2) 编程 第5页 共 页
void send_icmp(int sockfd,sockaddr_in send_addr); void recv_icmp(int sockfd,sockaddr_in send_addr); int main() { sockaddr_in addr[100]; SET_ADDR_PORT; int sockfd; sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP); if(sockfd<0) return 1; SET_ADDR_PORT; for(int i=0;i<100;i++) { } return 0; send_icmp(sockfd,send_addr[i]); recv_icmp(sockfd,send_addr[i]); sleep(3); } void send_icmp(int sockfd,sockaddr_in send_addr) { } static short int seq=0; char buf[8+8]; struct icmphdr *icmp=(struct icmphdr *)buf; icmp->type=ICMP_ECHO; icmp->code=0; icmp->checksum= CHECK_SUM; icmp->un.echo.id=getpid(); icmp->un.echo.sequence=seq++; int len=send(sockfd,buf,buflen); void recv_icmp(int sockfd,sockaddr_in send_addr) { char buf[256]; struct icmphdr *icmp; 第6页 共 页
cout<<"recv error"<ip_hl<<2; icmplen=n-ipheadlen; icmp=(struct icmphdr *)(buf+ipheadlen); if(icmp->type==ICMP_ECHOREPLY) cout<<"recv from "<
if(pid<0) exit(1); else if(pid==0){ //child B,use pipe1&2 cout<<"child B..."<0) cout<<"child B received:"<0) cout<<"child A received:"<
分享到:
收藏