网络程序设计6-传输层协议UDP和TCP.ppt
1,传输层协议UDP和TCP,2,由以前的知识可知,点到点通信是由网络互联层来实现的,网络互联层只屏蔽了不同网络之间的差异,构建了一个逻辑上的通信网络,因此它只解决了数据通信问题。端到端通信是建立在点到点通信基础之上的,它是比网络互联层通信更高一级的通信方式,完成应用程序(进程)之间的通信。端到端的通信是由传输层来实现的。,3,传输层端到端通信什么是端到端?,4,Internet 传输层协议,可靠按序递交(TCP)拥塞控制 流量控制连接建立不可靠的无序传递:UDP“尽力传递”IP的直接扩展不提供的服务:延迟保证带宽保证,5,多路复用/多路分解,=进程,=套接字,将接收到的数据段传递到正确的套接字,从多个套接字集合数据,用首部封装数据(以后用来多路分解),6,传输层端到端通信,7,传输层端口的概念为了识别传输层之上不同的网络通信程序(进程),在主机上,进行网络通信前,进程可以向系统提出动态申请,由系统(操作系统内核)返回一个本地惟一的端口号,也可以手动指定未使用的端口号,进程再通过系统调用把自己和这个特定的端口联系在一起,这个过程叫绑定(Binding)。每个要通信的进程都与一个端口号对应,传输层就可以使用其报文头中的端口号,把收到的数据送到不同的应用程序。,8,在TCP/IP协议中,传输层使用的端口号用一个16位的二进制数表示。因此,在传输层如果使用TCP协议进行进程通信,则可用的端口号共有216个。由于UDP也是传输层一个独立于TCP的协议,因此使用UDP协议时也有216个不同的端口。一些常用服务的TCP和UDP的众所周知端口号举例.。,9,无连接多路分解,用端口号创建套接字:DatagramSocket mySocket1=new DatagramSocket(99111);DatagramSocket mySocket2=new DatagramSocket(99222);UDP 套接字由两个因素指定:(目的IP地址,目的端口号),当主机收到UDP数据段:检查数据段中的目的端口号用端口号指示UDP数据段属于哪个套接字具有不同的源IP地址且/或源端口号的IP数据报指向同样的套接字,10,无连接多路分解(继续),DatagramSocket serverSocket=new DatagramSocket(6428);,11,面向连接的多路分解,TCP 套接字由4部分指定:源IP地址源端口号目的IP地址目的端口号接收主机使用所有四个值将数据段定位到合适的套接字,服务器主机支持很多同时的 TCP 套接字:每个套接字用4部分来标示Web服务器对每个连接的客户都有不同的套接字HTTP 将对每个请求有一个不同的套接字,12,面向连接的多路分解(继续),ClientIP:B,serverIP:C,SP:9157,DP:80,D-IP:C,S-IP:A,D-IP:C,S-IP:B,D-IP:C,S-IP:B,13,常用的众所周知的TCP端口号,14,常用的众所周知的UDP端口号,15,2561023之间的端口号通常都是由Unix系统占用的,以提供一些特定的Unix服务。现在IANA管理11023之间所有的端口号。任何TCP/IP实现所提供的服务都使用11023之间的端口号。客户端口号又称为临时端口号(即存在时间很短暂)。这是因为客户端口号是在客户程序要进行通信之前,动态地从系统申请的一个端口号,然后以该端口号为源端口,使用某个众所周知的端口号为目标端口号(如在TCP协议上要进行文件传输时使用21)进行客户端到服务器端的通信。综上所述,我们知道两台要通信的主机,每一端要使用一个二元地址(IP地址,端口号)才可以完成它们之间的通信。,16,用户数据报协议UDP,UDP数据报的封装及其格式使用UDP时应用进程发送的数据不能太长UDP协议在工作时是建立在IP协议之上的,UDP从进程的缓冲区接收进程每一次产生的输出,对每次输出都生成一个UDP数据报,然后把生成的UDP数据报直接封装在IP数据报中进行传输,因此在传输层使用UDP协议时,发送端不需要发送缓冲区,如图所示。,17,UDP数据报的封装,18,被封装在IP中的UDP数据报通过网络传输到目标主机的IP层后,由目标主机的UDP层根据目标端口号送到接收该数据的相应进程。UDP数据报的格式如图所示。,19,UDP数据报格式,20,从UDP协议的数据报格式可以看出,UDP对数据的封装非常简单,主要是增加了端口号与校验和,然后就可以直接通过IP层进行传输了,因此它具有以下特点:(1)UDP是一种无连接、不可靠的数据报传输服务协议。(2)UDP对数据传输过程中惟一的可靠保证措施是进行差错校验,如果发生差错,则只是简单地抛弃该数据报。(3)如果目标端收到的UDP数据报中的目标端口号不能与当前已使用的某端口号匹配,则将该数据报抛弃,并发送目标端口不可达的ICMP差错报文。,21,(4)UDP协议在设计时的简单性,是为了保证UDP在工作时的高效性和低延时性。因此,在服务质量较高的网络中(如局域网),UDP可以高效地工作。(5)UDP常用于传输延时小,对可靠性要求不高,有少量数据要进行传输的情况,如DNS(域名服务)、TFTP(简单文件传输)等。,22,TCP报文段的格式,23,1.建立连接 TCP使用“三次握手”建立一条连接。在建立一条连接时通信双方要交换三次报文。2关闭连接 由于TCP是一个全双工协议,因此在通信过程中两台主机都可以独立地发送数据,关闭一个连接一般要经过4次握手。,24,TCP连接的建立与关闭,25,TCP连接的建立与关闭,26,TCP的特点,通信前要建立连接支持可靠通信支持拥塞控制支持流量控制通信后需要断开连接只支持一对一通信数据没有边界(数据流),27,TCP与UDP的比较,28,传输层报文实例,UDP报文,29,传输层报文实例,TCP报文,30,UDP编程模式,31,recvfrom,函数原型:ssize_t recvfrom(int sockfd,void*buf,int len,unsigned int flags,struct sockaddr*from,socket_t*fromlen);ssize_t 相当于 int,socket_t 相当于int,这里用这个名字为的是提高代码的自说明性。,32,参数,sockfd:标识一个已连接套接口的描述字;buf:接收数据缓冲区;len:缓冲区长度;flags:调用操作方式;from:(可选)指针,指向装有源地址的缓冲区;fromlen:(可选)指针,指向from缓冲区长度值。,33,sendto,函数原型#include int sendto(SOCKET s,const char FAR*buf,int len,int flags,const struct sockaddr FAR*to,int tolen);s:一个标识套接口的描述字。buf:包含待发送数据的缓冲区。len:buf缓冲区中数据的长度。flags:调用方式标志位。to:(可选)指针,指向目的套接口的地址。tolen:to所指地址的长度。,34,connect,函数原型 int connect(int sockfd,const struct sockaddr*servaddr,socklen addrlen)函数的第一个参数sockfd为socket调用返回的套接口描述符。第二个参数指向套接口地址结构的指针,第三个参数为地址结构的大小。套接口地址结构中必须包含有服务器的IP地址和端口号。,35,Recv,send,函数原型 int recv(int socket,void*buffer,size_t length,int flags);int send(int socket,const void*buffer,size_t length,int flags);Flags的描述:,36,UDP的数据输出过程,UDP提供的是不可靠的数据传输服务,因此,UDP套接口并没有发送缓存;应用进程的数据在沿协议栈向下传递时,以某种形式复制到内核的缓存中,当数据链路层把数据传出去后这个副本就被丢弃;TCP会在底层将应用程序数据分片,UDP不会。,37,实验改变发送缓存大小的测试,广播和多播,单播通信:网络中单一的源节点发送封包到单一的目的节点。广播通信:将封包从一个节点发送到所有其他节点。多播通信:将封包从一个节点发送到其他多个网络节点的集合。,广播通信,广播、多播仅适用于UDP协议广播的负面作用是明显的:多个进程都发送广播数据,网络性能会受到影响。几乎所有路由器都不转发广播数据,广播程序仅应用于本地子网。,数据过滤过程,6,1 协议各层对接收帧的过滤过程,广播地址的分类,受限的广播,受限的广播地址是。该地址用于主机配置过程中IP数据报的目的地址,此时,主机可能还不知道它所在网络的网络掩码,甚至连它的IP地址也不知道。在任何情况下,路由器都不转发目的地址为受限的广播地址的数据报,这样的数据报仅出现在本地网络中。,指向网络的广播,指向网络的广播地址是主机号为全1的地址。A类网络广播地址为,其中netid为A类网络的网络号。一个路由器必须转发指向网络的广播,但它也必须有一个不进行转发的选择。,指向子网的广播,指向子网的广播地址为主机号为全1且有特定子网号的地址。作为子网直接广播地址的IP地址需要了解子网的掩码。例如,如果路由器收到发往的数据报,当B类网络128.1的子网掩码为时,该地址就是指向子网的广播地址;但如果该子网的掩码为,该地址就不是指向子网的广播地址。,指向所有子网的广播,指向所有子网的广播也需要了解目的网络的子网掩码,以便与指向网络的广播地址区分开。指向所有子网的广播地址的子网号及主机号为全1。例如,如果目的子网掩码为,那么IP地址是一个指向所有子网的广播地址。然而,如果网络没有划分子网,这就是一个指向网络的广播。,发送广播数据,SOCKET s=:socket(AF_INET,SOCK_DGRAM,0);/有效SO_BROADCAST选项BOOL bBroadcast=TRUE;:setsockopt(s,SOL_SOCKET,SO_BROADCAST,(char*),套接字选项,套接字选项和I/O控制命令用于改变套接字的默认行为主要的函数:getsockopt(SOCKET s,int level,int optname,char*optval,int*optlen);setsockopt(SOCKET s,int level,int optname,char*optval,int optlen);s:套接字句柄level:指定选项定义在哪个级别optname:套接字选项名称optval:指定一个缓冲区,用于选项的值optlen:optval所指缓冲区的大小,level,网络是分层的,每层上又有多个协议,因此套接字选项有不同的级别常见级别:SOL_SOCKET(对应应用层)IPPROTO_TCP(对应传输层的TCP协议IPPROTO_UDP(对应传输层的UDP协议)IPPROTO_IP(对应网络层的IP协议),optname,各级别的选项不同,同一级别不同协议的选项也可能不同,SOL_SOCKET级别的选项,SO_BROADCASTBOOL型设置套接字传输和接收广播消息。如果给定套接字已进行过设置,则返回TRUE。该选项只对不是SOCKET_STREAM类型的套接字有效SO_REUSEADDRBOOL型设置为TRUE,套接字可以被绑定到一个已经使用的本地地址。不能将两个监听套接字绑定到相同的本地地址,IPPROTO_IP级别的选项,IP_TTL设置和获取IP头中的TTL参数IP_ADD_MEMBERSHIP加入多播组IP_DROP_MEMBERSHIP离开多播组,程序实例,BOOL bBroadcast=TRUE;setsockopt(s,SOL_SOCKET,SO_BROADCAST,(char*)level:SOL_SOCKEToptname:SO_BROADCASToptval:TRUE,但需要进行类型转换optlen:一个bool值所需要的缓冲区大小,广播地址,SOCKADDR_IN bcast;bcast.sin_family=AF_INET;bcast.sin_addr.s_addr=INADDR_BROADCAST;/:inet_addr(255.255.255.255);bcast.sin_port=htons(4567);INADDR_BROADCAST此处等价于特殊地址“255.255.255.255”此地址用于对所处网络几乎没有了解的条件下一般的广播地址:IP地址中主机号为全1,接收广播数据,接收程序只需要将套接字绑定到广播端口,即可接收同一子网内的该端口上的广播数据SOCKADDR_IN sin;sin.sin_family=AF_INET;sin.sin_addr.S_un.S_addr=INADDR_ANY;sin.sin_port=:ntohs(4567);if(:bind(s,(sockaddr*),recv()与recvfrom(),recvfrom()还可以得到数据来源端的地址示例程序中用recv()也可以完成功能,多播(Multicast)通信,广播的负面作用是显而易见的,多播是将封包发送到多个节点的更为可行的方法。有许多向多个接收者传送信息的应用:例如交互式会议系统和向多个接收者分发邮件或新闻。如果不采用多播,目前这些应用大多采用TCP来完成(向每个目的地址传送一个单独的数据复制)。,多播地址,发送多播数据需要一个多播地址。每个多播地址代表一个多播组。多播地址的范围 多播组地址包括为1110的最高4bit和多播组号。它们通常可表示为点分十进制数,范围从,保留的多播地址,当把多播扩展到单个物理网络以外需要通过路由器转发多播数据时,复杂性就增加了。需要有一个协议让多播路由器了解确定网络中属于确定多播组的任何一个主机。这个协议就是Internet组管理协议(IGMP)。,组管理协议(IGMP),IPV4用于管理多播客户和他们之间关系的协议IGMP用于通知路由器对指定组的数据感兴趣终端加入多播组时,将指定TTL值,指明终端的多播程序想要经过多少个路由器发送和接收数据,接收多播的数据报的步骤,(1)加入一个多播组。(2)在指定的端口上进行监听。(3)接收并处理到达的多播数据报。(4)任务完成,离开多播组。(5)关闭插口描述符。,加入多播组,ip_mreqmcast;mcast.imr_interface.S_un.S_addr=INADDR_ANY;mcast.imr_multiaddr.S_un.S_addr=inet_addr(234.5.6.7);/多播地址为setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char*)通过设置套接字选项,加入多播组,ip_mreq结构,Typedef struct/多播地址struct in_addr imr_multiaddr;/将要加入或离开多播组的本地地址struct in_addr imr_interface;,离开多播组,ip_mreqmcast;mcast.imr_interface.S_un.S_addr=dwInterFace;mcast.imr_multiaddr.S_un.S_addr=dwMultiAddr;setsockopt(s,IPPROTO_IP,IP_DROP_MEMBERSHIP,(char*)通过设置套接字选项,离开多播组,接收多播数据,接收多播数据,必须加入特定的多播组,并将套接字绑定到特定的端口。char buf1280;int nAddrLen=sizeof(si);int nRet=:recvfrom(s,buf,strlen(buf),0,(sockaddr*),发送多播数据,向特定的组发送多播数据,并不必要加入这个组。准备好多播数据,准备好多播地址,即可调用sendto()发送char sz=This is just a test.rn;while(TRUE):sendto(s,sz,strlen(sz),0,(sockaddr*),带有源地址的IP多播,带源地址的IP多播允许加入组时指定要接收哪些成员的数据。可以使用“包含”和“排除”两种方式加入组“包含”方式:指定多个有效的源地址,套接字仅接收来自这些源地址的数据“排除”方式:指定多个有效的源地址,套接字不接收来自这些源地址的数据,“包含”方式,使用IP_ADD_SOURCE_MEMBERSHIP选项配置套接字,加入多播组,并指定数据的源地址选项的值为一个ip_mreq_source结构使用IP_DROP_SOURCE_MEMBERSHIP从集合中移除源地址,ip_mreq_source结构,struct ip_mreq_source/多播组地址struct in_addr imr_multiaddr;/指定的源地址struct in_addr imr_sourceaddr;/本地地址接口struct in_addr imr_interface;,“排除”方式,使用IP_ADD_MEMBERSHIP选项加入组,此时使用的就是“排除”方式使用IP_BLOCK_SOURCE选项来指定要派出的源地址,TCP和UDP的优点及适用场合,