期末考试完成,特此存档
选择题
A.x86平台网络字节序是大端顺序
B.double数据类型在网络中传输不需要考虑转换字节顺序
C.htonl()函数是将主机字节序转换成网络字节序
D.整数类型在网络中传输不需要考虑转换字节顺序
( B )服务器的作用是文件传输。
A、 DNS
B、FTP
C、WEB
D、DHCP
关于服务器端编程下列说法正确的是(A )
A. 循环迭代服务器在一个时刻只能处理单个客户请求
B. 循环迭代服务器处理客户请求的时效性更好
C. 并发服务器的实现需要多线程操作
D.并发服务器必须通过为每一个到来的客户创建一个子服务线程来实现。
在UDP协议中,源端口号50000属于哪一种端口域(C )。
A、知名端口域
B、注册端口域
C、动态端口域
D、静态端口域
在DNS协议中,使用的端口是( B )。
A、20
B、53
C、45
D、 156
下列哪种应用不是典型的P2P应用( D)
A. 迅雷
B. Napster
C. 酷狗
D. FTP服务
以下哪个套接字选项可以设置套接字接收超时时间的( B )。
A.SO_RCVLOWAT
B.SO_RCVTIME
C.SO_REUSEADDR
D.SO_RCVBUF
在Internet中用一个三元组可以在全局中唯一标识一个应用成进程,这不包括下列哪一种?( D )
A、网络层协议
B、IP地址
C、端口号
D、传输层协议
请求建立连接时TCP包头中的( A )标志位有效。
A、SYN
B、RST
C、PSH
D、URG
在Windows系统中,对于一个没有设置任何套接字选项的阻塞套接字,调用recv接收对方的数据,对方发送数据前进程突然崩溃,下列哪种情况将会发生( C )
B.recv立刻返回SOCKET_ERROR
C.recv立刻返回0
D.recv在等待很长一段时间后返回0
以下哪个场景不适合采用数据报套接字编程(C)
A. 多播形式实现传输应用
B. 广播形式实现传输应用
C. Internet上大文件的传输
D.音频数据的实时传输
套接字编程中,关于connect()、bind()函数的说法错误的是( C)
A. connect()函数关联的是对方的地址
B. bind()函数绑定的是自己的地址
C. 数据报套接字中,connect()函数的调用会让客户端向服务器端发起请求连接包
D.在原始套接字编程中,也可以使用connect()函数关联对方的地址
原始套接字编程中,IP_HDRINCL控制选项被设置,则代表着( A)
A. 发送函数在数据构造时需要用户来构造IP首部
B. 发送函数在数据构造时由协议栈来自动填充
C. 发送函数在数据构造时需要用户来构造TCP首部
对于原始套接字,内核会把以下哪种接收到的IP数据报传递到原始口( A )。
A. 内核处理后的IGMP分组
B. IP分片数据
C. TCP分组
D.认识其协议字段的IP数据报
以下函数中不会产生阻塞的是( D )。
A、send( )
B、sendto( )
C、connect( )
D、Listen( )、
管理计算机通信的规则称为:( A)。
A、协议 B、介质 C、服务 D、网络操作系统
UDP协议提供的是( B )类型。
A、面向连接的数据传输服务
B、无连接的数据传输服务
C、无连接的虚电路服务
D、可靠地数据传输服务
在DNS协议中,使用的端口号是( B )。
A、20 B、53 C、45 D、 156
如果想实现TCP SYN端口扫描,即发送一个TCP SYN包来判断目的主机端口是否开放,可以采用哪种编程技术(A)?
A. 流式套接字
B. 数据报套接字
C. 原始套接字
D. 标准套接字
下面关于ICMP协议论述不正确的是(C )。
A、ICMP协议同IP协议一样位于网络层。
B、ping 命令进行网络检测时使用ICMP 报文。
C、ICMP协议可以被黑客用来探测主机的开放端口。
D、ICMP协议可以完成主机重定向功能。
以下哪个套接字选项可以设置套接字接收缓存大小(D)。
A.SO_RCVLOWAT
B.SO_RCVTIME C.
SO_REUSEADDR
D.SO_RCVBUF
在原始套接字编程中,使用recv函数接收到的数据为(D)。
A.对于IPv4,是去掉了IP首部的数据
B.对于IPv4,是包含IP首部的完整IP数据报
C.对于IPv6,是包含IPv6首部和所有扩展首部的完整数据报
D.不确定,与是否开启IP_HDRINCL选项有关
对于原始套接字,内核会把以下哪种接收到的IP数据报传递到原始口( A)。
A. 内核处理后的IGMP分组
B. IP分片数据
C. TCP分组
D.认识其协议字段的IP数据报
一个TCP/IP通信端点由结构sockaddr_in中的(B)字段来标识。
A、sin_family, sin_port
B、sin_family, sin_port, sin_addr
C、sin_family, sin_addr
D、sin_port, sin_addr
以下关于Select函数说法正确的是(B )。
A、Select函数是重叠IO模型用来获取I/O状态的函数
B、Select函数是用来获取一组套接字的I/O状态的函数
C、Select函数只用来获取一个套接字的I/O状态
以下函数中不会产生阻塞的是(D)。
A、send( )
B、sendto( )
C、connect( )
D、Listen( )
在Windows系统中,对于一个没有设置任何套接字选项的阻塞套接字,调用recv接收对方的数据,对方发送数据前进程突然崩溃,下列哪种情况将会发生(C)。
A.recv永远不会返回
B.recv立刻返回SOCKET_ERROR
C.recv立刻返回0
填空
I/O复用模型中,用来获取一组套接字的IO状态的函数是________。
以太网利用_________协议获得目的主机IP地址与MAC地址的映射关系。
ICMP数据报文的类型有____________和___________两类。
Windows事件对象分为两种工作状态,即_________状态和_________状态。
套接口建立时I/O模式默认处于_________状态。
原始套接字编程时,为了使网卡能接收到所有经过它的数据帧,需要使用I/O控制函数___________的____________命令将网卡设置为混杂工作模式。
Windows套接字I/O模型中,伸缩性最好,最为复杂的I/O模型是_______________。
答案
Select
ARP
查询、控制
授信、未授信
阻塞
WSAIoctl SIO_RCVALL
完成端口
1. IP数据报选项的两大功能是数据传输控制和 。
2. 从应用程序实现、套接字实现和协议实现三个层次来观察数据发送的过程,数据发送在实施过程中主要涉及两个缓冲区:应用程序发送缓冲区和____________发送缓冲区。
3. ICMP报文有两种类型查询报文和 。
4. 在网络中,每一台机器上都有一个 高速缓存,这个高速缓存存放了最近IP 地址到硬件地址直接的映射关系。
5. 从消息的处理机制来看,套接字编程可以分为_________和_________两种I/O模型。
6. 一个完整的网间通信可以简化为一个五元组来标识两个通信进程,分别是 (_________ 、本地IP地址、本地端口号、远程IP地址和_________)。
7. Windows套接字I/O模型中,常见的异步I/O模型是有:WSAAsynSelect模型、__________模型、_________模型和完成端口模型。
1. 阻塞
2. 点到点通信
3. 应用程序、套接字
4. 查询报文、差错报文
5. ARP
6. 阻塞、非阻塞
7. 协议 远程端口号
WSAEventSelect 重叠套接口
简答论述题
1、accept( )为什么要返回一个套接口?或者说,为什么要为每一个连接创建一个套接口来处理?UDP服务器端为什么不需要多个套接口?
如果函数accept()执行成功,则返回值是有内核自动生产的一个全新套接口描述符,代表与客户的TCP连接。对该客户后续的所有操作,都使用这个新的套接口描述符,因此把它叫已连接套接口描述符,至于原来那个监听套接口,它仍然用于监听其它客户发送的连接请求,而且仍处于监听模式,因此把它叫做监听套接口描述符,当有多个客户连接过来时,一个监听套接口可以派生出多个已连接套接口。
UDP是无连接的,没有三次握手,在收到数据报后会直接处理。
*2、阻塞模式的流式套接字程序中,发送端调用一次send函数发送数据,接收端需要调用几次recv函数接收数据,为什么?)
答:
1、流式套接字的流传输特点,tcp如何对数据打包跟调用send函数交付多少数据给tcp没有直接的关系,对于使用tcp的应用程序来说,没有“数据边界”的概念,接收操作返回的时机和数量是不可预测的。
2、数据的接收处理需要考虑网络中的各种可能性,针对一定长度的待传输数据,发送端send函数的调用次数与接收端recv函数的调用次数是完全独立的,在发送端调用一次send传入的数据可以在另一端多次调用recv来获取,而调用recv一次也可能返回多次send调用传入的数据。4分
所以,对流式套接字不能预知所接收的数据大小是否超过了进程所定义的接收缓冲区大小时,可以通过循环调用recv()函数来接收流式套接字中的数据。2分
3、有阻塞模式的数据报套接字程序,客户端调用三次sendto函数发送数据,第一次发送500字节的’A’,第二次发送0字节的数据,第三次发送1000字节的’B’,服务器端调用四次recvfrom函数接收数据,recvfrom函数的接收缓存设为800字节。请问:服务器在四次接收操作时分别能接收到多少字节的数据,内容是什么,recvfrom函数的返回值是什么?为什么?(本题6分)
解答:
第一次接收操作接收到完整的500字节的报文,recvfrom()函数返回500;
第二次接收操作接收到的0字节的报文,recvfrom()函数返回 0;
第三次接收操作接收1000字节的报文,recvfrom()函数返回1000,第二个报文后续的200字节内容被截断丢弃;
第三次接收操作接收1000字节的报文,recvfrom()函数返回 -1,报文被丢弃
第四次接收操作依赖于套接字的工作模式,如果是阻塞模式,则接收函数阻塞,如果设置了接收超时,则在超时时间到时返回接收超时错误;如果是非阻塞模式,则接收函数立刻返回,错误类型是WSAEWOULDBLOCK.
*4、请给出I/O复用模型的编程思想。
答:
select()可以监测一组套接字的集合,可以实现同一时刻监测多个网络事件,进而可实现并发。 (3分)
IO复用编程流程:设置等待的网络事件---调用select阻塞等待网络事件---判断哪类套接字发生网络事件---处理相应的网络事件。4分
5、在数据报套接字编程中,如何解决噪声问题,即接收到的数据不是来自发送数据的目的地址?
噪声的产生主要有以下两种情形:
- 无关的数据源发送的无关数据,主要表现在数据来源的IP地址或端口号不是正确的发送方地址;
- 相关的数据源发送的无关数据,主要表现在数据来源的IP地址和端口号是正确的,但发送的数据是无关的,比如长度不足、类型不对或内容有误等。
针对第一种情形,我们可以通过增加对数据源的判断来确切地接收已知来源的数据
如果客户在一段时间内只有一个唯一的服务器通信,那么对无关来源的判断还可以通过数据报套接字的连接模式来实现。在套接字发送和接收数据前,先调用connect()函数来注册通信的对方地址,那么该函数能够保证此后接收到的数据只能是连接声明的数据源发回的,其他数据源发送的数据报都不会被协议栈提交给该套接字。
除了对无关来源的判断外,针对第二种情形,我们还需要对数据内容特征进行判断,比如:
1)增加对数据长度的判断,过小的报文可能由于传输环节上的接收截断导致,需要丢弃。
2)增加对数据类型的定义和判断,当通信双方会交换多种类型的通信报文时,程序设计者习惯于在数据的开始部分增加固定位置和长度的类型字段。这种类型字段有助于进行数据内容和格式的标识,方便接收方处理,那么在接收数据后,应针对不同的数据类型进行不同的处理。
3)增加对数据发送源的身份鉴别为了保护资源的安全性,实际应用中的很多应用程序会增加对数据发送源的身份鉴别,比如合法的用户名口令、授权的IP地址等等。
6.简述TCP协议与UDP协议的区别。
Tcp是面向连接的协议,也就是说,在收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来。使用TCP协议传输数据,TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。当数据从A端传到B端后,B端会发送一个确认包(ACK包)给A端,告知A端数据我已收到!
UDP协议就没有这种确认机制,这就是为什么说TCP协议可靠,UDP协议不可靠,提供这种可靠服务,会加大网络带宽的开销,因为“虚拟信道”是持续存在的,同时网络中还会出现大量的ACK和FIN包。TCP协议提供了可靠的数据传输,但是其拥塞控制、数据校验、重传机制的网络开销很大,不适合实时通信,所以选择开销很小的UDP协议来传输数据。UDP协议是无连接的数据传输协议并且无重传机制,会发生丢包、收到重复包、乱序等情况。
1.基于连接与无连接。
2.UDP不提供可靠性,不能保证数据能够到达目的地。
3.对系统资源的要求(TCP较多,UDP少)。
4.UDP结构较简单。
5.TCP面向字节流模式,TCP会保证服务端按顺序接收到全部的字节流,UDP面向数据报模式,不保证顺序性。
很明显,当数据传输的性能必须让位于数据传输的完整性、可控制性和可靠性时,选择TCP协议。当强调传输性能而不是传输的完整性时,如音频和多媒体应用,UDP是最好的选择。在数据传输时间很短,以至于此前的连接过程成为整个流量主体的情况下,UDP也是一个好的选择,如DNS交换。UDP较低的开销使其有更好的机会去传送管理数据。TCP丰富的功能有时会导致不可预料的性能低下。
什么是UDP,说明UDP的特点:用户数据报协议(UDP)是网络层之上常用的一个非常简单的协议,它主要是在IP层之上提供了协议端口的功能,以标识源主机和目标主机上通信的进程。特点:协议简单,无连接,不可靠,传输速率高。
什么是TCP,说明TCP的特点:传输控制协议(TCP)提供一种面向连接的,可靠的数据流服务。特点:协议复杂,面向连接,可靠,传输速率低。
7.Winsock中网络连接与套接口的关闭函数有哪几个?
Connect() WSAconnect() shutdown() closesocket() WSAcleanup()
*8.请简述http协议的工作流程。
浏览器登录新浪网站为例
1)首先启动dns协议进行地址解析,以获取相应网址域名的IP地址。1分
2)以dns获取的IP地址为目的地址,向新浪网的WEB服务器发起TCP三次握手连接,一般TCP连接的端口号是80。 2分
3)一旦建立了TCP连接,Web浏览器就会向Web服务器发送请求命令。例如:GET/sample/hello.jsp HTTP/1.1。 Web服务器回应请求发应答信息,例如应答:HTTP/1.1 200 OK ,应答的第一部分是协议的版本号和应答状态码。2分
4)Web服务器和浏览器之间进行信息交互。 1分
5)交互完成,Web服务器关闭TCP连接。(一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码:Connection:keep-alive TCP。连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。)1分
9.采用阻塞式I/O模型时,套接字函数recv()的返回值有哪几种?分别对应什么情况?
大于0,成功接收到数据,然后继续接受
等于0,连接关闭
小于0,接收发生错误
10.closesocket()函数和shutdown()函数有何差别?
1) 如果关闭 读,则接受缓冲区的未读出的所有数据都将丢失,以后不会再接受任何数据
2) 如果关闭 写,如果输出缓冲区内有数据,则所有的数据将发送出去后将发送一个 FIN 信号 而 close 则是关闭该 socket,马上发送 FIN 信号,所有的未完成发送或者接受的数据都将被丢失 对于慢速网络,应该先进行 shutdown,然后一定的时间延迟,再 close 该 socket.
shutdown可以分别关闭读写或者同时关闭读写:
1) 如果关闭读,则接受缓冲区的未读出的所有数据都将丢失,以后不会再接受任何数据
2) 如果关闭写,如果输出缓冲区内有数据,则所有的数据将发送出去后将发送一个FIN信号
而close则是关闭该socket,马上发送FIN信号,所有的未完成发送或者接受的数据都将被丢失
对于慢速网络,应该先进行 shutdown,然后一定的时间延迟,再 close 该 socket.
11.原始套接字编程的特点及应用场合。
特点:
允许访问底层传输协议,
提供了普通套接字所不具备的功能,
能够对网络数据包进行某种程度的控制操作。
场合
1)特殊用途的探测应用。
2)基于数据包捕获的应用。
3 )特殊用途的传输应用。
具体而言,原始套接字提供普通TCP和UDP套接字不提供的以下三种能力:
1)发送和接收ICMPv4、IGMPy4 和ICMPv6等分组。原始套接字能够处理在IP头中预定义的网络层上的协议分组,如ICMP、IGMP等。举例来说,ping程序使用原始套接字发送ICMP回射请求并接收ICMP回射应答。多播路由守护程序也使用原始套接字发送和接收IGMPv4分组。
这个能力还使得使用ICMP和IGMP构造的应用程序能够完全作为用户进程处理,而不必往内核中额外添加代码。
2)发送和接收内核不处理其它协议字段的IPv4数据包。对于8位IPv4协议字段,大多数内核仅仅处理该字段值为1 ( ICMP协议)、2 ( IGMP协议)、6 (TCP协议)、17 ( UDP协议)的数据报,然而为协议字段定义的其他值还有很多,在IANA的“Protocol Numbers”中有详细的定义。举例来说,OSPF路由协议既不使用TCP也不使用UDP,而是直接通过IP协议承载,协议类型为89。如果想在一个没有安装OSPF路由协议的系统上处理OSPF数据报文,那么实现OSPF的程序必须使用原始套接字读写这些IP数据包,因为内核不知道如何处理协议字段为89的IPv4数据包,这个能力还延续到IPv6。
3)控制IPv4首部。使用原始套接字不仅能够直接处理IP协议承载的协议分组,而且能够直接控制IP首部,通过设置(IP_ HDRINCL)套接字选项可以控制IPv4首部字段的自行构造。我们可以利用该选项构造特殊的IP首部以达到某些探测和访问需求。
场合
1)特殊用途的探测应用。原始套接字提供直接访问硬件酒信的相关能力,其工作层次决定了此类套孩字具有灵活的数据构造能力,应用程序可以利用原始能接学强TCP依,包的结构和内容,实现面向特殊用途的探测和扫描。因此,原始套接字适用于要求数据包构造灵活性高的应用。
2)基于数据包捕获的应用。对于从事协议分析或网络管理的人来说,各种人侵检测、流量监控以及协议分析软件是必备的工具,这些软件都具有数据包捕获和分析的功能。原始套接字能够操控网卡进人混杂模式的工作状态,从而达到捕获流经网卡的所有数据包的目的。基于此,使用原始套接字可以满足数据包捕获和分析的应用需求。
3 )特殊用途的传输应用。原始套接字能够处理内核不认识的协议数据,对于一些特殊应用,我们希望不增加内核功能,而是完全在用户层面完成对某类特殊协议的支持,原始套接字能够帮助应用数据在构造过程中修改IP首部协议字段值,并接收处理这些内核不认识的协议数据,从而完成了协议功能在用户层面的扩展。
原始套接字的灵活性决定了这种编程方法受到了许多黑客和网络管理人员的欢迎,但是由于涉及复杂的控制字段构造和解释工作,使用这种套接字类型完成网络通信并不容易,需要程序设计者对TCP/IP协议有深人的理解,同时具备深厚的网络程序设计经验。
*12.TCP流传输的特点是什么?针对TCP流传输特点,有什么样的合理策略能编程实现有效的发送或接收?
tcp流传输特点:数据是作为字节流递交给接收者的,没有内在的“消息”或“消息边界”的概念,当发送者调用发送函数进行数据发送时,发送者并不清楚数据真实的发送情况,协议栈中TCP的实现根据当时的网络状态决定以多少字节为单位组装数据,并决定什么时候发送这些数据,接收者在读取TCP数据时并不知道给定的接收函数调用将会返回多少字节。接收操作返回的时机和数量是不可预测的,必须在应用程序中正确处理 3分
接收策略: 1)循环接收
- 且根据接收状态来相应编程处理
发送策略:发送成功不等于发送有效,程序要正确处理发送的失败模式 4分
13使用UDP进行网络应用编程时可在哪些具体操作上考虑可靠性问题
解答:
由于UDP协议是一个不可靠的协议,使用UDP进行数据传输的应用程序会因为网络环境、主机环境的差异带来数据传递过程中发生丢失、乱序、重复等问题,那么在程序运行过程中需要考虑:
发送操作:发送出去的数据可能会丢失,需要考虑超时重传问题;发送目的地可能并不存在,需要判断目的应用程序的状态。
接收操作:接收到的数据可能重复,需要判断重复数据;接收到的数据可能是噪音,需要排除噪音;接收到的数据可能乱序,需要考虑重组;可能无法接收到预期的数据,需要考虑反馈确认和流量控制问题。
*14.套接字有哪些种类,分别有什么特点?
答
1)流式套接字,提供面向连接、可靠的数据传输服务,数据无差错、无重复的发送,且按发送顺序接收;内设流量限制,避免数据超流限;数据被看做是字节流,无长度限制;(2分)
2)数据报套接字。提供无连接服务;数据包以独立包形式发送,不提供无差错保证,数据可能丢失或重复,并且接收顺序混乱。(2分)
3)原始套接字。当使用前两种套接字无法完成数据收发任务时,原始套接字提供了更加灵活的数据访问接口,使用它可以在网络上对socket进行编程,发送和接收网络层上的原始数据包。(式允许访问底层传输协议的一种套接字类型,提供了普通套接字所不具备的功能,能够对网络数据报进行某种程度的控制操作)(2分)
*15.Windows平台提供了哪些套接字的I/O模型?其中异步的I/O模型分别是哪些?
答:
windows平台提供了7种套接字的I/O模型:阻塞模型、非阻塞模型、I/O复用模型、基于消息的WSAsyncselect模型、基于事件的WSASelect模型、I/O重叠模型、完成端口模型。(3分)
其中基于消息的WSAAsyncselect模型、基于事件的WSASelect模型、I/O重叠模型、完成端口模型是异步模型。(2分)
举例说明异步模型思想(2分)
*16.阻塞与非阻塞通信的区别。
答:
从消息的处理机制来看,套接字编程可以分为阻塞和非阻塞两种I/O通信模式。
阻塞模式是指在指定套接字上调用函数执行操作时,在没有完成操作之前,函数不会立即返回。例如:在阻塞模式下调用recv()函数...(3分)
非租塞模式是指在指定套接字上调用函数执行操作时,无论操作是否完成,函数都会立即返回。例如:在非租塞模式下调用recv()函数...
*17.请描述流式套接字和数据报套接字的应用差别?
流式套接字是传输层基于TCP协议为基础的。是基于可靠的数据流传输服务,这种服务的特点是面向连接、可靠。面向连接的特点决定了流式套接字的传输代价大,且只适合于一对一的数据传输;而可靠的特点意味着上层应用程序在设计开发时不需要过多地考虑数据传输过程中的丢失、乱序、重复问题。主要应用场合:
1)大数据量的数据传输应用。因为数据传输量大,对数据传输的可靠性要求比较高。
2)可靠性要求高的场合(3分)
数据报套接字传输层是基于UDP协议,不可靠的报文传输协议,用于提供无连接的报文传输服务,该特点决定了数据报套接字的传输非常灵活,具有资源消耗小、处理速度快的优点。
主要应用场合:
1)音频、视频的实时传输应用。比如网络视频软件的应用。
2)广播或多播的传输应用。比如:多媒体系统的多播或广播、udp传输音视频数据。(4分)
18.TCP程序的工作模型隐含着通信标识五元组的建立过程。这五元组在TCP的客户与服务端是由哪些函数分别确定的?
客户端:
socket()函数确定通信协议,
connect()函数确定远地地址和远地端口及本地地址,
服务端:
socket()函数确定通信协议,
bind()函数本地地址和本地端口,
accept()函数确定远地地址和远地端口。
PS:
三元组:(协议,本地地址,本地端口号);(在网络中用一个三元组可以在全局唯一标志一个进程:(协议,本地地址,本地端口号)这样一个三元组,叫做一个半相关(half-association),它指定连接的每半部分。)
五元组:(协议,本地地址,本地端口号,远地地址,远地端口号)(即两个协议相同的半相关才能组合成一个合适的相关,或完全指定组成一连接。
19.同步和异步模式的区别
同步和异步概念与消息的通知机制有关。对于消息处理者而言,在同步的情况下,由处理消息者自己去等待消息是否被触发;在异步的情况下,由触发机制来通知处理消息者,然后进行消息的处理。同步和异步仅仅是关于所关注的消息如何通知的机制,而不是处理消息的机制。
PS
网络通信中的同步机制和异步机制是描述通信模式的概念。
同步机制,是指发送方发送请求后,需要等待接收到接收方发回的响应后,才接着发送下一个请求;
异步机制,和同步机制正好相反,在异步机制中,发送方发出一个请求后,不等待接收方响应这个请求,就继续发送下个请求。
在同步机制中,所有的请求在服务器端得到同步,发送方和接收方对请求的处理步调是一致的;
在异步机制中,所有来自发送方的请求形成一个队列,接收方处理完成后通知发送方。
同步/异步是针对请求而言,对应socket编程中的 connect() 和 accept()
同步/异步是针对客户端和服务端相互之间的数据通信模式
阻塞/非阻塞是针对处理而言,对应socket编程中的 send() 和 recv()
阻塞/非阻塞是针对多线程之间的数据通信模式
异构环境下的网络程序设计需要考虑哪些问题?
1) 字节顺序:不同的平台以不同的方式存放一个二进制数。最常见的有两种格式:大数在前的字节顺序和小数在前的字节顺序。大数在前的字节顺序是指将一个多字节数的 高序字节存储在内存的起始地址(大端序);而小数在前的字节顺序则相反,将低序字节存储在内存的起始地址(小端序)。
2) 字的长度:不同的实现对于相同的数据类型可能有不同的表示长度。
3) 字节定界问题:不同的平台上为结构体( struct )或共同体( union )打包的方式也是不同的,这取决于所有数据类型的位数及机器的定界限制。
4 、为什么在数据结构 struct sockaddr_in 中,成员变量 sin_addr 和 sin_port 需要转换为网络字节顺序,而 sin_family 不需要呢?
Sin_addr 和 sin_port 分别封装在包的 IP 和 UDP 层,必须要是网络字节顺序。 Sin_family 域只是被内核使用来决定在数据结构中包含什么类型的地址,没有发送到网络上,所以它必须是本机字节顺序
基于UDP的网络程序,请分析其服务器端和客户端的工作流程如何?在各个工作阶段,需要使用哪些winsock函数?
答:a) 服务端
使用WSAStatup()函数检查系统协议栈的安装情况
使用socket函数创建服务器端通信的套接口
使用bind ()函数将创建的套接口与服务器地址绑定
建立连接后使用recvfrom()函数接收数据和客户地址,使用sendto ()函数发送数据<
使用closesocket ()函数关闭套接口
调用WSAcleanup结束windows Sockets Api的调用
- b) 客户端
使用WSAStatup()函数检查系统协议栈的安装情况
使用socket函数创建客户端通信的套接口
使用connect ()关联服务器端地址
建立关联后使用send ()函数发送数据或使用recv ()函数接收数据;
若没建立关联使用sendto()函数发送数据或使用recvfrom ()函数接收数据
使用closesocket ()函数关闭套接口
调用WSAcleanup结束windows Sockets Api的调用
windows下编写基于TCP的网络程序,分析其服务器端和客户端的工作流程如何?在各个工作阶段,需要使用哪些winsock函数?(12分)
- 答:a) 服务端
使用WSAStatup()函数检查系统协议栈的安装情况
使用socket函数创建服务器端通信的套接口
使用bind()函数将创建的套接口与服务器地址绑定
使用listen()函数使服务器套接口做好接收连接请求的准
使用accept()函数接收来自客户端由connect发出的连接请
建立连接后使用send()函数发送数据或使用recv()函数接收数据
使用closesocket()函数关闭套接口
调用WSAcleanup结束windows Sockets Api的调用
- b) 客户端
使用WSAStatup()函数检查系统协议栈的安装情况
使用socket函数创建客户端通信的套接口
使用connect()发出连接请求
建立连接后使用send()函数发送数据或使用recv()函数接收数据
使用closesocket()函数关闭套接口
调用WSAcleanup结束windows Sockets Api的调用
网络I/O通信模型评价
1阻塞IO模型
阻塞IO模型是网络通信中进行IO操作的一种常用模型,这种模型的优点是使用非常简单直接。但是当需要处理多个套接字连接时,串行处理多套接字的IO操作会导致处理时间延长、程序执行效率降低等问题。在这种情况下,如何及时处理多个IO请求是关键。
针对这一问题,有两个解决思路。
思路一:使用多线程并发处理多个IO请求。
在这种思路下,我们将对多个IO请求的串行等待改为多线程等待,即一种IO操作使用一个线程,但是这样的实现方案会增加线程的启动和终止以及维护线程运行和同步等操作,进而增大了程序的复杂性和系统开销。
思路二:异步、非阻塞处理多个IO请求。
在这种情况下,仍然用单线程实现网络操作,但是在对IO处理上应用一些机制来及时捕获IO条件满足的时机,用单线程模拟多线程的执行效果,此时的关键问题是如何确定网络事件何时发生。
2非阻塞IO模型
非阻塞IO模型使用简单的方法来避免套接字在某个IO操作上阻塞等待,应用进程不再睡眠等待,而是可以在等待I/O条件满足的这段时间内做其他的事情。在函数轮询的间隙可以对其他套接字的I/O操作进行类似的尝试,这样对于多个套接字的网络I/O而言,非阻塞的方法可以避免串行等待IO带来的效率低下问题。
但是由于应用程序需不断尝试接口函数的调用,直到成功完成指定的操作,这对CPU时间是较大的浪费。另外,如果设置了较长的延迟时间,那么最后一次成功的IO操作对于IO事件发生而言有滞后时间,因此这种方法并不适合对实时性要求比较高的应用。
3I/O复用模型
从表面上看,与阻塞IO模型相比,I/O复用模型似乎没有明显的优越性,在使用了系统调用select()后,要求两次系统调用而不是一次,还稍显劣势。但是使用IO复用模型的好处在于select()函数可以等待多个套接字准备好,即使程序在单个线程中仍然能够及时处理多个套接字的IO事件,达到跟多线程操作类似的效果,这避免了阻塞模式下的线程膨胀的问题。
尽管select()函数可以管理多个套接字,但其数量仍然是有限的,套接字集合中默认包含64个元素,最多可以管理的套接字数量为1024个。另外,用集合的方式管理套接字比较烦琐,而且每次在使用套接字进行网络操作前都需要调用select()函数判断套接字的状态,这也给CPU带来了额外的系统调用开销。
另外,select()函数还有其他方面的应用。在工业控制以及实时性要求较高的环境下,高精度的定时器对提高工作效率有很重要的意义,除了应用于网络中多个I/O事件的捕获之外,select()函数的超时处理能力还可以应用于对精度要求比较高的定时应用中。
4基于消息的WSAAsyncSelect模型.
WSAAsyncSelect模型的优点是在系统开销不大的情况下可以同时处理多个客户的网络IO。但是,消息的运转需要有消息队列,通常消息队列依附于窗口实现,有些应用程序可能并不需要窗口,为了支持消息机制,就必须创建一个窗口来接收消息,这对于一些特殊的应用场合并不适合。另外,在一个窗口中处理大量的消息也可能成为性能的瓶颈。
5基于事件的WSAEventSelect模型
WSAEventSelect模型不依赖于消息,所以可以在没有窗口的环境下比较简单地实现对网络通信的异步操作。该模型的缺点是等待的事件对象的总数是有限制的(每次只能等待64个事件),在有些应用中可能会因此受限。
6重叠IO模型
与前面介绍过的阻塞、非阻塞、IO复用、WSAAsyncSelect 以及 WSAEventSelect等模型相比,WinSock的重叠IO模型使应用程序能达到更佳的系统性能。因为它和其他5种模型不同的是,使用重叠模型的应用程序通知缓冲区收发系统直接使用数据。也就是说,如果应用程序投递了一个10KB大小的缓冲区来接收数据,且数据已经到达套接字,则该数据将直接被拷贝到投递的缓冲区。而在前5种模型中,当数据到达并拷贝到某个套接字接收缓冲区中时,应用程序会被系统通知可以读入的字节数,当应用程序调用接收函数之后,数据才从某个套接字缓冲区拷贝到应用程序的缓冲区。由此看来,重叠IO的效率优势就在于减少了一次从IO缓冲区到应用程序缓冲区的拷贝。
7完成端口模型
完成端口模型是应用程序使用线程池处理异步IO请求的一种机制,在Windows服务平台上比较成熟,是伸缩性最好的,也是迄今为止最为复杂的一种IO模型。当应用程序需要管理上千个套接字时,利用完成端口模型往往可以达到最佳的系统性能。
实际上完成端口是Windows IO 的一种结构,它可以接收多种对象的句柄,除了对套接字对象进行管理之外,还可以应用于文件对象等。
阻塞套接字的socket函数
将可能阻塞套接字的socket API调用分为以下四种,总结起来就是和网络有关的函数时阻塞式的:
1.输入操作:recv()、recvfrom()、WSARecv()和WSARecvfrom()函数。
以阻塞套接字为参数调用该函数接收数据。如果此时套接字缓冲区内没有数据可读,则调用线程在数据到来前一直睡眠。
2.输出操作: send()、sendto()、WSASend()和WSASendto()函数。
以阻塞套接字为参数调用该函数发送数据。如果套接字缓冲区没有可用空间,线程会一直睡眠,直到有空间。
3.接受连接:accept()和WSAAcept()函数。
以阻塞套接字为参数调用该函数,等待接受对方的连接请求。如果此时没有连接请求,线程就会进入睡眠状态。
4.外出连接:connect()和WSAConnect()函数。对于TCP连接,客户端以阻塞套接字为参数,调用该函数向服务器发起连接。
该函数在收到服务器的应答前,不会返回。这意味着TCP连接总会等待至少到服务器的一次往返时间。
阻塞模式套接字的不足表现为,在大量建立好的套接字线程之间进行通信时比较困难。当使用“生产者-消费者”模型开发网络程序时,为每个套接字都分别分配一个读线程、一个处理数据线程和一个用于同步的事件,那么这样无疑加大系统的开销。其最大的缺点是当希望同时处理大量套接字时,将无从下手,其扩展性很差。
综合题
请补全下一个程序代码,程序功能要求实现回射TCP服务器程序,客户端向服务器发送字符串,服务器接收到该字符串后显示在屏幕上,并将该字符串再回射给客户端。
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT 27015
int _tmain(int argc, _TCHAR* argv[])
{ WSADATA wsaData;
int iResult;
SOCKET ServerSocket = INVALID_SOCKET;
SOCKET AcceptSocket = INVALID_SOCKET;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
sockaddr_in addrClient;
int addrClientlen = sizeof(sockaddr_in);
iResult =____________________________________ //初始化TCPIP协议栈
if (iResult != 0)
{
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ServerSocket =_____________________________________//创建流式套接字
if(ServerSocket == INVALID_SOCKET)
{
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
SOCKADDR_IN addrServ;
addrServ.sin_family = AF_INET;
addrServ.sin_port = htons(DEFAULT_PORT); addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
iResult = ________________________________________ //将套接字everSocket绑定到地址结构体addrServ
if (iResult == SOCKET_ERROR)
{ printf("bind failed with error: %d\n", WSAGetLastError());
closesocket(ServerSocket);
WSACleanup();
return 1;
}
iResult =____________________________; //以系统定义最大数目监听SeverSocket
if(iResult == SOCKET_ERROR)
{ printf("listen failed !\n");
closesocket(ServerSocket);
WSACleanup();
return -1;
}
printf("TCP server starting\n");
int err;
//循环等待客户请求建立连接,并处理连接请求
while(true)
{
AcceptSocket = ________________________________________//接受客户连接,将客户地址存于addrrClient,并返回服务套接字AcceptSocket
if( AcceptSocket == INVALID_SOCKET)
{
printf("accept failed !\n");
closesocket(ServerSocket);
WSACleanup();
return 1;
}
//循环接收数据,并对返回的iResult值分三种情况进行判断
while( TRUE)
{
memset(recvbuf,0,recvbuflen);
iResult = ______________________________________;//接收数据,并将接收数据放入recvbuf
if (iResult > 0)
{ __________________________________________________
____________________________________________________
____________________________________________________
____________________________________________________
____________________________________________________
____________________________________________________
}
else if (iResult == 0)
{
____________________________________________________
____________________________________________________
____________________________________________________
}
else
{
printf("recv failed with rror: %d\n",WSAGetLastError() );
closesocket(AcceptSocket);
closesocket(ServerSocket);
WSACleanup();
return 1;
}
}
}
closesocket(ServerSocket);
closesocket(AcceptSocket);
WSACleanup();
return 0;
}
iResult = WSAStartup(MAKEWORD(2,2), &wsaData); 2分
ServerSocket = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);2分
iResult =bind(ServerSocket,(const struct sockaddr*)& addrServ, sizeof(SOCKADDR_IN)); 2分
iResult = listen(ServerSocket, SOMAXCONN); 2分
AcceptSocket = accept(ServerSocket,(sockaddr FAR*)& addrClient, &addrClientlen); 2分
iResult = recv(AcceptSocket, recvbuf, recvbuflen, 0); 2分
{printf("Bytes received: %d\n", iResult);
iSendResult = send( AcceptSocket, recvbuf, iResult, 0 );
if (iSendResult == SOCKET_ERROR)
{
printf("send failed with error: %d\n", WSAGetLast Error());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
printf("Bytes sent: %d\n", iSendResult);} 8分
printf("Current Connection closing, waiting for the next connection...");
closesocket(AcceptSocket);
break;
点击数:119
(☆ω☆)