网络软件设计面向连接与无连接服务服务与协议制作主讲段景山段景山2引入回到基本流程申请套接字资源时,需要指明套接字类型SOCK_STREAMSOCK_DGRAM指明了套接字类型后,究竟产生了哪些影响?程序流程的不同数据传输服务的不同!段景山3面向连接程序流程Servers=socket(SOCK_STREAM);bind(s,…);listen(s,5);while(1){ns=accept(s,…);recv(ns,…);send(ns,…);closesocket(ns);}closesocket(s);Clients=socket(SOCK_STREAM);connect(s,server,…);send(s,…);recv(s,…);closesocket(s);段景山4无连接程序流程ServerClients=socket();bind(s,…);while(1){recvfrom(s,remote,…)sendto(s,remote,…)}closesocket(s);s=socket();sendto(s,remote,…);recvfrom(s,remote,…);closesocket(s);段景山5流程比较Servers=socket(SOCK_STREAM);bind(s,…);listen(s,5);while(1){ns=accept(s,…);recv(ns,…);send(ns,…);closesocket(ns);}closesocket(s);Servers=socket();bind(s,…);while(1){recvfrom(s,remote,…)sendto(s,remote,…)}closesocket(s);段景山6流程比较Clients=socket();sendto(s,remote,…);recvfrom(s,remote,…);closesocket(s);Clients=socket(SOCK_STREAM);connect(s,server,…);send(s,…);recv(s,…);closesocket(s);段景山7流程比较无连接的流程打开套接字通信关闭套接字面向连接的流程打开套接字建立连接通信关闭连接关闭套接字问题:除了流程不同这样的表观现象外,面向连接和无连接究竟有哪些关键的、本质的差别?三个阶段段景山8数据报与字节流服务数据报服务由无连接协议--UDP提供发送:以报文为单位如果报文超过最大可发送长度,将拒绝发送每次用户交付的数据,都将封装在一个UDP报文发送接收:以报文为单位如果接收缓冲区小于接收的报文长度,将无法得到全部接收数据,剩余丢失即便接收缓冲区足够大,每次也只能接收一个UDP报文--类似信件超重--类似取包裹时,包裹太大实验验证段景山9数据报与字节流服务字节流服务由面向连接协议--TCP提供对字节流的理解:对用户交付的数据以流的形式,不加限制发送:用户可发送“任意”长度的报文,TCP实体可根据通信的需要分拆用户一次交付的数据为多个TCP报文,发送;或组合用户多次交付的数据为单个TCP报文。接收:用户得到的数据并不受到TCP报文大小限制,接收缓冲小时,可得到TCP报文的一部分接收缓冲大时,可一次得到多个TCP报文实验验证1.1段景山10可靠服务与不保证可靠服务面向连接提供可靠的通信质量当通信中丢失报文时,TCP层可在不通知用户的情况下得到恢复当通信中出现重复报文时,不会交给用户,而引起误会无连接不保证通信可靠性当通信中丢失报文时,UDP并不进行差错恢复当通信中出现重复报文时,也会交给用户,是否引起误会由用户自行负责实验设计1.2段景山11源和目的的限定“连接”与通信源和目的连接由源和目的确定,在通信过程中,不能改变在已建立连接的套接字,不能向另外的目的发送数据不能接收非连接对端送来的数据在通信过程中,用户不再(不能)指定源和目的“无连接”与通信源和目的在通信过程中,可向任意目的发送数据在通信过程中,可收到任意源送来的数据实验验证2.1段景山12多路复用方面的表现多路复用程序可同时与多个对等实体通信多路复用是否因“面向连接”或“无连接”而不同?“连接”与多路复用每个套接字对应一个连接实现多路复用必须实现同时检测多个套接字--select()“无连接”与多路复用无连接是否必须使用select?哪些情况下,会在无连接方式下使用select?提示:select除了能检测多个套接字,还能检测多个设备段景山13服务与协议能否在A类套接字上使用B模式下的函数来取得相应的服务?用户通过套接字函数获得服务套接字函数的具体功能应由相应的协议实现服务和协议之间一般是一一对应的服务和协议之间可以不完全对应,在某些场合下可提供一定的灵活性和便利在(面向连接)流套接字上能够使用sendto和recvfrom等服务原语吗?在(无连接)数据报套接字上能使用connect和send、recv等原语吗?如果能,会产生怎样的效果呢?段景山14服务与协议字节流和数据报服务流套接字上使用sendto和recvform函数是否能获得数据报类型的服务?数据报套接字上使用send和recv是否能获得字节流服务?可靠性流套接字会不会因为使用sendto和recvfrom而变得无法保证可靠性了?数据报套接字使用send和recv是否变得可靠了?源和目的的限定流套接字在使用sendto函数后,是否可以向任意对端发送数据?数据包套接字使用send后,是否只能向一个目的发送?函数的交叉使用究竟在哪些方面影响了服务段景山15函数的交叉使用套接字函数可在两种方式下使用,且功能相同可在两种方式下使用,但功能不同只能在一种方式下使用通过对函数交叉使用的测试,深入体会两种服务方式的不同以及服务与协议之间的关系socket()bind()listen()accept()recv()send()closesocket()recvfrom()sendto()connect()select()setsockopt()ioctlsocket()shutdown()通信类控制类getpeername()getsockname()getsockopt()信息类htonl()htons()ntohl()ntohs()inet_addr()inet_ntoa()辅助类段景山16函数的交叉使用在两种方式下使用且功能相同socket()bind()closesocket()控制类、信息类、辅助类段景山17函数交叉使用的测试目标无连接方式,数据报套接字(SOCK_DGRAM)listen能否得到正确返回值accept能否得到正确返回值connect能否得到正确返回值recv能否收到数据send能否发送数据讨论内容:1、能否使用?2、函数本身产生的效果3、对整个机制的影响4、相关实验证明段景山18函数交叉使用的测试目标面向连接方式,流套接字(SOCK_STREAM)recvform()能否得到接收数据sendto()能否正确发送数据段景山19函数交叉使用的测试结果可在两种方式下使用(,但结果不同)connectrecvsendsendtorecvfrom只能在一种方式下使用listenaccept段景山20进一步测试数据报套接字与面向连接服务使用面向连接的服务是否能约束源和目的?在建立“连接”前能否使用recv和send在建立“连接”前使用recvfrom和sendto是否不受源和目的限制在建立“连接”后能否使用recv和send,是否受到源和目的限制在建立“连接”后使用recvfrom和sendto,是否受到源和目的限制是否能获得字节流服务在建立连接后使用recv和send是否能形成字节流的服务效果?是否能获得可靠服务保证段景山21进一步测试字节流套接字与无连接通信服务在连接建立之前使用recvfrom和sendto在连接建立之后使用recvfrom和sendto能否突破连接源和目的限制是否是数据报的服务是否不保证可靠性段景山22小结(服务与协议)面向连接与无连接表面的不同SOCK_STREAM与SOCK_DGRAM流程不同使用不同函数深层次的区别字节流服务与数据报服务可靠性保证与不保证连接的约束与维持限定套接字数据只能在连接的两个端点之间传输有时可以使用相同的函数有时可以使用相同的流程段景山23小结(服务与协议)交叉使用函数的体会数据流向的约束字节流套接字不能使用sendto和recvform来突破流向约束数据报套接字可以通过connect来约束套接字数据的流向。字节流或数据报服务与所使用的函数无关字节流套接字上无论使用send还是sendto、recv还是recvfrom,都是字节流服务数据报套接字上无论使用什么函数,仍是数据报服务可靠性仍与套接字类型有关,与使用的函数无关段景山24小结(服务与协议)体会服务与协议的关系是相互关联,又相对独立的套接字类型实际是指明底层协议套接字函数是底层协议程序在实现相关功能基础上,提供的服务接口--是服务原语部分套接字函数可以在两种不同的套接字下使用,提供了一定的灵活性。约束套接字数据流向这类与协议无太大关联的功能可在两种套接字上使用字节流/数据报服务及可靠性保证的与协议直接关联的功能就必须依靠协议段景山25服务与协议的关系(一)服务与协议分别了不同内容一般情况下,协议和服务是统一的。某种类型的协议提供某种类型的服务,某种类型的服务需要某种类型的协议实现。段景山26服务与协议的关系(二)服务与协议之间又是相对独立的,服务并不要求一定要用哪个协议实现,甚至可能由另一种类型的协议实现面向连接的协议无连接的协议面向连接的服务无连接的服务()()()()思考1思考2面向连接的协议无连接的服务()()无连接的协议面向连接的服务()()段景山27小结(服务与协议)服务原语与协议函数的设计模型服务原语与协议函数本质上程序中的函数recv()、send()等是服务原语,与具体协议无关具体协议有各自的实现函数服务原语与协议实现函数有一定的对应关系,但服务函数可通过套接字类型选择协议实现函数send()TCP_send()UDP_send()传输层应用层Socket接口段景山28小结(服务与协议)服务原语与协议函数的设计模型与TCP_send对等的一定是TCP_recv协议对等而与send对等的可以是recvfrom或recv服务是上下层之间send()TCP_send()传输层应用层Socket接口recvfrom()TCP_recv()main()main()对等对等