《《计算机网络编程》复习题.docx.pdf》由会员分享,可在线阅读,更多相关《《计算机网络编程》复习题.docx.pdf(14页珍藏版)》请在三一文库上搜索。
1、1?基本概念 1? 1?什么是协议 计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则。1.2. TCP/IP协议的四层体系结 构 应用层(Telnetx FTP、HTTP DNS、SNMP、SMTP) 传输层(TCP、UDP) 网络层(IP、ICMP、IGMP) 链路层(以太网、令牌环网、FDDI、IEEE802.3) 1? 3?IP地址的结构、分类、多播(或称组播) 目前使用的:EP协议为ipv4 (即工P协议的第四版),使用32位二进制表示结构: 网络号主机号 分类:A,B,C,D,E等五类地址,见下表 类别类标识地址范围第一字节网络地址长度最大网络数最大主机数选用范围 A
2、类 0 1 126 1 字节 126 16777214 大型网络 B类 10 128 191 2字节 16382 65534 中型网络 C类 110 192?223 3字节2097150 254 小型网络 D类1110 224.0.0.0? 239.255.255.255 224?239 多点播送 E类 11110 240?247 保留地址 直接广播地址:主机号为全1的IP地址; 多播: 1)一对多的通信,一个源点发送到多个终点; 2)标识一个多播的标识符即为一个D类地址; 3)使用IGMP (网际组管理协议)协议,首部的协议字段值为2 4)多播地址只能用于目的地址,不能用于源地址; 5)对多
3、播数据报不产生ICMP差错报文; 多播分两种:局域网范围的硬件多播;因特网范围的多播,因为大部分主机是通过局域网接入到因特网 的,因此在多播的最后阶段,还是要在局域网范围内进行硬件多播。 1? 4?多播(或称组播)地址,如何映射到MAC地址 组播IP地址,即D类地址,范围是224.0.0.0 239.255.255.255; MAC地址的前25位是固定的,后23位与IP地址的后23位相同 IP地址 1110 yyyy yxxx xxxx xxxx xxxx xxxx xxxx MAC地址 0000 0001 0000 0000 0101 1110 Oxxx xxxx xxxx xxxx xxx
4、x xxxx (16进制) 0 1 0 0 5 e 1? 5?标识网络中的两个通信的进程或一条连接 五元组(协议,本地IP地址,本地端口号,远程TP地址,远程端口号) 1? 6?socket (套接字)的三种协议类型及其应用场合 1.9. UDP的C/S通信模型 协议类型应用场合socket函数屮的protocol值 SOCK_STREAM TCP IPPROTO_TCP SOCK_DGRAM UDP IPPROTO_UDP SOCK_RAW raw sockets IPPROTO_ICMP socket (int af, int type, int protocol)函数中,当第二个参数为A
5、FJNET 时, 第三个参数type的值可以为:SOCK_STREAM (流式套接字)、SOCK_DGRAM (数据报 套接字)、 SOCK_RAW (原始套接字),详情见下表: 1 ? 7 ? 写代码:创建socket 1) TCP SOCKET tcpSocket = socket(AF_INET ZSOCK_STREAM, IPPROTO_TCP); 2) UDP SOCKET udpSocket = socket(AF_INET ZSOCK_DGRAMZ IPPROTO_UDP); 3)原始套接字 SOCKET icmpSocket = socket(AF_INET, SOCK_RAM
6、, IPPROTO_ICMP); 1.8. TCP的c/s通信模型 Server Client 建立与服务器的连接 1.10.服务器端的两种绑定方式的区别 IP地址端口参数 方式1 INADDR_ANY 非0值 所有网卡都可接收连接,所有人都可 连接 方式2 IP地址非0值某网卡接收,指定人群连接 函数bind 原型为:int bind (SOCKET sz const struct sockaddr *namez int namelen) 代码如下: SOCKET listenSocket; struct sockaddr_in service; listenSocket = socket(
7、AF_INET Z SOCK_STREAM, IPPROTO_TCP); / 绑定方式1: service?sin_port = htons(9999); service.sin_addr?s_addr = inet_addr(INADDR_ANY); / 绑定方式2: service.sin_port = htons(9999); service.sin_addr?s_addr = inet_addr( n12 7.0.0.1n); bind(listenSocket, (SOCKADDR *) 函数丄isten中第二个参数的含义 函数原型为:int listen (SOCKET sz in
8、t backlog); 第二个参数backlog :设置等待连接队列的最大长度,若设置为SOMAXCONN,则表 示可用的 最大长度。 1? 12?在网络通信屮,怎样传输一个字符串( 可能含有汉字 ) Server Client 统一字符编码为UTF-8,传输时,先传输字符串的长度,再传输字符串内容。2?程序设计 2? 1?写代码:两个线程,交替打印数字 步骤: WSAStartup (),初女台化winsock socket (),仓ij建TCP型的socket bind(),绑定服务器的IP、PORT listen(),监听socket while (continue) accept ()
9、,接收客户端的连接 创建新线程,传入通信用的socket,与客户端进行通信 closesocket(), 关闭socket WSACleanup (),释放winsock资源 代码: / * * * main.cpp *多线程程序 *两个线程,分别打印线程号+数字 / #include #include include CALLBACK myThread(void *p); int main() HANDLE handles2; handles0=(HANDLE)_beginthreadex(NULL, 0, myThread, NULL, 0, NULL); handles1=(HANDLE
10、)_beginthreadex(NULL, 0, myThread, NULL, 0, NULL); WaitForMultipleObjects (2 Z handles, true, INFINITE); CloseHandle(handles0); CloseHandle(handles1); return 0; unsigned int CALLBACK myThread(void *p) unsigned int for (int i = 1;i #include #include #pragma comment(lib, nws2_32n ) / 线程:处理一个客户机的网络通信。
11、unsigned int CALLBACK tcpThread(void *p); int main() int iResult; WORD wVersionRequested; WSADATA wsaData; SOCKET listenSocket; SOCKET acceptSocket; struct sockaddr_in service; HANDLE handles10; wVersionRequested = MAKEWORD(2/ 2); /* Initializing Winsock */ iResult = WSAStartup(wVersionRequested, if
12、 (iResult != 0) printf( nWSAStartup failed with error: %dn“, iResult); return -1; /* create a tcp socket */ listenSocket = socket(AF_INET Z SOCK_STREAM, IPPROTO_TCP); if (listenSocket = INVALID_SOCKET) printf ( ncreate socket f alied with error : %dn,f , WSAGetLastError (); WSACleanup(); return -1;
13、/* bind the socket */ service.sin_family = AF_INET; service?sin_port = htons (9999); service?sin_addr?s_addr = inet_addr( n 127.0.0.1 n); iResult = bind(listenSocket A (SOCKADDR *) if (iResult = SOCKET_ERROR) printf( Hbind failed with error:%dn“ z WSAGetLastError(); closesocket( 丄istenSocket); WSACl
14、eanup (); return -1; /* listen for incoming connection requests */ iResult = listen (listenSocket z SOMAXCONN); if (iResult = SOCKET_ERROR) printf ( Hlisten failed with error:%dnn, WSAGetLmstError (); closesocket(listenSocket); WSACleanup(); return -1; printf ( “listening on socket.n n); /* accept n
15、ew incoming connections */ int again = 0; while (again #include #pragma comment (lib, ,f ws2_32 n ) int main() WSAData wsaData; WORD wVersionRequested; int iResult; struct sockaddr_in service; SOCKET listenSocket; wVersionRequested = MAKEWORD(2 f2); iResult = WSAStartup(wVersionRequested, if (iResul
16、t != 0) printf ( n WSAStartup failed with error : %dn !, , iResult); return - 1; listenSocket = socket(AF_INET Z SOCK_DGRAM, IPPROTO_UDP); if (listenSocket = INVALID_SOCKET) printf (create socket failed with error: %dn n, WSAGetLastError (); WSACleanup(); service.sin_family = AF_INET; service . sin_
17、addr . s_addr = inet_addr (* 127.0.0.1 n ); service.sin_port = htons (9999); iResult = bind(listenSocket z (SOCKADDR *) if (iResult = SOCKET_ERROR) printf( Hbind failed with error:%dnH, WSAGetLastError (); closesocket(listenSocket); WSACleanup (); return -1; struct sockaddr_in client_adcir; int len
18、= sizeof (client_addr); while (1) /* do something: *recvfrom() *sendto() */ closesocket (listenSocket); WSACleanup(); return 0; 2? 4?连接型UDP 般用于哪一方?什么场合?一般用于客户端; 要求内核进行UDP包的过滤; 2? 5?广播程序,每隔3秒广播本地时间 步骤: WSAStartup(),初始化winsock socket(), 创建socket set sockopt (),允许广播 while (continue) get Cur rent Time (
19、),获取本地时间sendto(),发送数据 Sleep (),暂停3秒 closesocket (),关闭socket WSACleanup (),释放winsock资源 代码: / * *广播服务器端程序 *每3秒广播服务器端的时间 */ #include #include #include #pragma comment (lib, ,f ws2_32 n ) void getcurtime(char* curtime) titm;/time?h time(/time.h sprintf (curtime, n%snJ ctime( int main() int iResult; WORD
20、 wVersionRequested; WSADATA wsaData; SOCKET serverSocket; struct sockaddr_in service; char on = 1; char msg256; serverSocket = socket(AF_INETZ SOCK_DGRAM, 0); setsockopt (serverSocket, SOL_SOCKET Z SO_BROADCAST, / 允许发广播包 service?sin_family = AF_INET; service?sin_port = htons(9999); service.sin_addr.
21、s_addr = htonl(INADDR_BROADCAST); while (1) getcurtime(msg); sendto(serverSocket, msg z strlen(msg)rQf (sockaddr *) printf( n%snn ,msg); Sleep(3000);/* sleep 3 seconds between send */ closesocket (serversocket); WSACleanup(); return 0; 2? 6?多播( 或称组播 ) 程序,每隔3秒多播本地时间步骤: WSAStartup (),初女台化winsock socke
22、t (),仓ij建socket setsockopt (),允许广 播while (continue) getCurrentTime (),获取本地时间sendtoO,发送数据到某D类地址Sleep (),暂 停3秒 closesocket(), 关闭socket WSACleanup (),释放winsock资源 代码: / * *多播服务器端程序 *每3秒广播服务器端的时间 */ #include #include #include #pragma comment (lib z nws2_3211 ) void getcurtime(char* curtime) tm;/time?h ti
23、me(/time?h sprintf (curtime, 11 %sn H z ctime ( ) int main() int iResult; WORD wVersionRequested; WSADATA wsaData; SOCKET serversocket; struct sockaddr_in service; char on = 1; char msg256; serverSocket = socket(AF_INET, SOCK_DGRAM, 0); setsockopt(serverSocket z SOL_SOCKETf S 0_BROAD CAST, / 允许发广播包
24、service.sin_family = AF_INET; service.sin_port = htons (9999); service?sin_addr?s_addr = inet_addr(”226?6?6?6“); printf ( ”每3秒向组226 ? 6.6.6发包,告之本机的时间n” ); while (1) getcurtime(msg); sendto(serverSocket, msg, strlen(msg) r 0A (sockaddr *) printf( H%snu,msg); Sleep (3000);/* sleep 3 seconds between se
25、nd */ closesocket(serverSocket); WSACleanup(); return 0; 3?协议分析 3? 1?IP数据报头部最大 / 小长度、头部选项最大 / 小长度,最多记录路由个数 头部最小长度:20 Bytes 头部最大长度:60 Bytes 选项最小t度:0 Bytes 选项最小长度:40 Bytes 最多记录路由:9个 3? 2?程序设计步骤:MyPing (源主机发送类型为8代码为0的“回送请求报文”,当目标主机收到该报文时,将标 识符、序号、数据区复制以组成类型为0代码为0的“冋送应答报文”,发送给源主机。) 1)创建原始套接字; 2)设置套接字的超时
26、选项(如6秒); 3)构造ICMP数据报:类型为8代码为0回送请求; 4)构造TP数据报,将上述的ICMP数据报作为IP数据报的数据部分;设置超时选项; 5)发送IP数据报到目标IP地址、端口; 6)若收到目标主机的类型为0代码为0的回头应答报文,则表示目标地址、端口号可达; 3? 3?程序设计步骤:路由MTU发现 1)创建原始套接字(ICMP协议); 2)打开选项; 3)构造IP报文: 4)填写头部:报文头部长度设置为最大,不允许分片; 5)填写数据:TCP数据报; 当路由器发现报文长度太长, 需要分片, 但报文头部设置为不允许分片,则路由器丢弃该报 文,并发送ICMP报文给源主机;本地收到
27、ICMP报文后,将报文长度设置为收到的ICMP报文长 度,再次重新发送IP数据报。直到源主机收到来自目的主机的TCP确认报文 , 最后一次发送的 报文长度就是该路径的MTUo 3? 4?程序设计步骤:记录两主机之间经过的路由 1)创建原始套接字; 2)打开记录路由选项:选项类为0;选项号为7;选项长度为39;指针初值为4; 初始时,指针指向存放第一个工P地址的位置,经过各路由器时,存入每个路由器的IP 地 址,指针的值每次加4;最多可存放9个IP地址; 3? 5?程序设计步骤:FTP断点续传 1) USER用户名 2) PASS 口令 3) TYPE I (文件类型:二进制) 4) FILE
28、F (文件的数据结构:文件结构) 5) MODE S (文件的传输方式:流) 6) PORT IP端口号(客户端 :EP、端口号) 7) REST N (N:己下载的字节数) 8) RETR文件名 9) QUIT (退出) 3? 6?程序设计步骤:FTP多线程下载 1)创建N个线程,通过“SIZE文件名”获収文件大小M; 2)每个线程历经3?5中的1)-6 )步; 3)第i 个线程:REST I*M/N; 4) RETR文件名; 5) QUIT 3? 7?FTP主动、被动方式的区别及适用的场合 FTP数据连接有两种方式:主动方式和被动方式; 主动和被动是就服务器而言的; 主动方式:服务器主动向
29、客户端发起连接,客户端使用PORT命令将本地的IP地址和端口 号告诉服务器,服务器使用20端口连接客户端的端口; 被动方式:服务器等待客户端的连接,客户端使用PASV命令使服务器处于被动传输模式, 服务器使用PORT命令将服务器的端口(大于1024的非特权端口)告诉客户端,客户端向服务 器发起连接; 主动模式适用场合:服务器在子网内; 被动模式适用场合: 客户端在子网内; 客户端的防火墙可能会阻塞某些非特权端口,导 致服 务器无法主动连接客户端: 3? 8?程序设计步骤:HTTP断点续传 1)确定已下载数量n; 2) get方法头部: range : bytes=n-(从n处开始下载) 3?
30、9?程序设计步骤:HTTP文件多线程下载 通过HTTP协议的head方法,提取cont ent-length内容,获取文件的大小M; 将文件分成n份,每个线程都向服务器提出文件下载请求,第i个线程的get方法头nP Range: bytes=(i-1 )*M/N - i * M/N; 3? 10?HTTP状态管理方法 HTTP是无状态的。若要对购物车进行状态管理,方法有: 1)通过get方法,传递参数 2)利用表单中的隐藏域 3) session 4) cookie 4?扩展 4? 1?TCP连接池的设计方法 定义连接池的大小N; 创建一个大小为N的TCP套接字数组,每个套接字绑定到本地IP和端口号; 创建一个标记数组,大小为N,分别标记对应的套接字是否空闲; 当有新的连接请求时,在套接字数组中取出一个空闲的套接字,进行连接,并将该套接字 的状态改为“正在使用”; 当有连接结束时,释放该连接,并将对应的状态改为“空闲”; 4? 2?服务器端程序如何判断客户端程序是否在线 客户端按照一定的时间间隔向服务器发送心跳包,以通知服务器自己是在线的。若服务器 在间隔一定的时间(如5分钟)后,没有收到心跳包,则认为该客户端不在线,服务器进行相 应的数据保存及资源释放处理。 5?其他