《03.基于UDP协议的Socket编程(2015)》由会员分享,可在线阅读,更多相关《03.基于UDP协议的Socket编程(2015)(36页珍藏版)》请在金锄头文库上搜索。
1、网络编程技术网络编程技术课程课程基于UDP协议的Socket编程讲课人:潘讲课人:潘 炜炜TelTel:1357223749913572237499E-mailE-mail:西北工业大学计算机学院西北工业大学计算机学院2教学目的和重点v目的掌握基于UDP协议的Socket编程方法v重点基于UDP协议的Socket编程模型和程序设计流程3知识点vUDP协议的工作流程v基于UDP协议的Socket编程模型v服务器程序设计思路v客户机程序设计思路v程序示例分析4UDP协议的特点vUDP协议的特点特点:UDP不要求保持一个连接UDP没有因接收方认可收到数据包(或当数据包没有正确抵达而自动重传)而带来的
2、开销。设计UDP的目的是用于短应用和控制消息UDP要求的网络带宽比TCP更小。5使用UDP协议的场合v传送的数据对顺序和可靠性要求不高v简单的发送接收的一次通信形式v传输的数据量较少v发送广播或多播信息6打电话与发短信的区别打电话与发短信的区别7问题v透过现象看本质v为什么一个人同时只能应付一个人打来的为什么一个人同时只能应付一个人打来的电话,而可以应付多个人的短信?电话,而可以应付多个人的短信?8UDP和TCP的区别vTCP 面向连接,完整的“流”vUDP 无连接,一个一个独立的报文vUDP和TCP的区别决定了UDP的编程模式和TCP有很大差别9接收数据接收数据recvfrom()基于UDP
3、协议的Socket编程模型编程模型服服务务器器绑定套接字绑定套接字bind() 客客户户机机发送数据发送数据sendto()绑定套接字绑定套接字bind()数据传输数据传输数据传输数据传输关闭套接字关闭套接字closesocket()创建套接字创建套接字socket()初始化套接字初始化套接字WSAStartup()注销套接字注销套接字WSACleanup()创建套接字创建套接字socket()初始化套接字初始化套接字WSAStartup()发送数据发送数据sendto()接收数据接收数据recvfrom()关闭套接字关闭套接字closesocket()注销套接字注销套接字WSACleanup
4、()模型(一)模型(一)10基于UDP协议的Socket编程模型v模型(一)的特点:应用程序双份是对等的。使用数据报套接字通信时都经过6个阶段:初始化套接字接口创建套接字绑定套接字发送/接收数据,交换信息关闭套接字注销套接字接口11基于UDP协议的Socket编程模型v模型(一)的特点:双方必须确切地知道对方的网络地址,且将约定好的自己的网络地址绑定到自己的套接字上。每次发送或接收数据报时,所使用的sendto()和recvfrom()中要包括对方的网络地址信息。recvfrom()在没有收到数据前,默认情况下会阻塞,程序不向下执行。12接收数据接收数据recvfrom()基于UDP协议的So
5、cket编程模型服服务务器器绑定套接字绑定套接字bind() 客客户户机机发送数据发送数据sendto()数据传输数据传输数据传输数据传输关闭套接字关闭套接字closesocket()创建套接字创建套接字socket()初始化套接字初始化套接字WSAStartup()注销套接字注销套接字WSACleanup()创建套接字创建套接字socket()初始化套接字初始化套接字WSAStartup()发送数据发送数据sendto()接收数据接收数据recvfrom()关闭套接字关闭套接字closesocket()注销套接字注销套接字WSACleanup()模型(二)模型(二)13基于UDP协议的Soc
6、ket编程模型v模型(二)的特点:应用程序双份是不对等的。服务器要先行启动,处于被动的等待访问状态;客户机则可随时主动请求访问服务器。完成一次通信时服务器要经过6个阶段:初始化套接字接口创建套接字绑定套接字发送/接收数据,交换信息关闭套接字注销套接字接口而客户机不需要绑定套接字。14基于UDP协议的Socket编程模型v模型(二)的特点:服务器将套接字绑定到周知的端口或指定的端口,且客户机必须确切地知道服务器端套接字使用的网络地址。客户机套接字使用动态分配的自由端口,不需要进行绑定。服务器事先不必知道客户机套接字使用的网络地址。客户机必须先发送数据报,服务器收到后才能知道客户机的地址,才能给客
7、户机回送数据报。15UDP流程socket(),创建套接字ss0.0.0.0:0 - 0.0.0.0:0bind( ),绑定本地地址结构s192.168.0.1:8888 - 0.0.0.0:0需不需要获知对端的IP地址和端口?16sendto()v发送一个数据报int sendto ( SOCKET s, const char FAR * buf, int len, int flags, const struct sockaddr FAR * to, int tolen);v返回值成功:返回实际发送的字节数失败:返回SOCKET_ERROR指定对端的地址结构指定对端的地址结构长度17recv
8、from()v接收一个数据报int recvfrom ( SOCKET s, char FAR* buf, int len, int flags, struct sockaddr FAR* from, int FAR* fromlen); v返回值成功:返回实际接收的字节数连接已终止:0失败:返回SOCKET_ERROR接收发过来的地址结构18问题v如果返回返回0,意味着什么?19答案vTCP 字节流可以发送0字节报文若接收到0字节,意味着连接被优雅地关闭vUDP 数据报可以发送0字节报文若接收到0字节,意味着报文长度为0并关闭连接vrecvfrom()和sendto()也可以用在TCP中此时
9、,接收到0字节意味着连接被优雅地关闭一般不这样用20s = socket(AF_INET, SOCK_DGRAM, 0);struct sockaddr_in localaddr;memset(void *)&localaddr, 0, sizeof(localaddr);localaddr.sin_family = AF_INET;localaddr.sin_addr.s_addr = htonl(INADDR_ANY);localaddr.sin_port = htons(8888);bind(s, (struct sockaddr *)&localaddr, sizeof(localad
10、dr);char buf6;recvfrom(s, buf, 6, 0, NULL, 0);closesocket(s);程序范例 recvfrom()21SOCKET s;s = socket(AF_INET, SOCK_DGRAM, 0);struct sockaddr_in localaddr;memset(void *)&localaddr, 0, sizeof(localaddr);localaddr.sin_family = AF_INET;localaddr.sin_addr.s_addr = htonl(INADDR_ANY);localaddr.sin_port = hton
11、s(0);bind(s, (struct sockaddr *)&localaddr, sizeof(localaddr);struct sockaddr_in peeraddr;memset(void *)&peeraddr, 0, sizeof(peeraddr);peeraddr.sin_family = AF_INET;peeraddr.sin_addr.s_addr = inet_addr(127.0.0.1);peeraddr.sin_port = htons(8888);sendto(s, Hello, 6, 0, (struct sockaddr *)&peeraddr, si
12、zeof(peeraddr);closesocket(s);程序范例 sendto()22示例1v示例1:利用基于UDP协议的Socket编程实现客户机与服务器的简单通信。服务器启动后将在8888号端口监听客户机启动后主动连接服务器端并发送字符串“Hello”服务器接收并显示“Hello”服务器客户机HelloHello23示例1v演示UdpClient程序与UdpServer程序间通信24TCP流程服务器服务器客户端客户端acceptconnectsend/recvsend/recvsend/recv25UDP流程服务器服务器客户端客户端sendto/recvfromsendto/recvf
13、romsendto/recvfrom26TCP编程模式main() socket(); bind(); listen(); accept();thread() recv(); send();thread() recv(); send();thread() recv(); send();main() socket(); connect(); send(); recv();main() socket(); connect(); send(); recv();main() socket(); connect(); send(); recv();27UDP编程模式main() socket(); bi
14、nd(); recvfrom(); sendto(); recvfrom(); sendto(); recvfrom(); sendto();main() socket(); bind(); sendto(); recvfrom();main() socket(); bind(); sendto(); recvfrom();main() socket(); bind(); sendto(); recvfrom();28示例2v利用Socket编程实现基于UDP协议的广播通信。通信步骤:创建数据报套接字,只有数据报套接字支持广播通信。绑定套接字于指定的地址和端口。通过套接字选项设置数据报套接字的
15、广播属性。通过sendto()函数发送广播信息,只能使用sendto函数,发送地址为INADDR_BROADCAST(广播地址)。通过recvfrom()函数接收广播消息。29示例2:演示UDP广播发送数据的例子v宏定义INADDR_BROADCAST表示广播地址,即0xFFFFFFFF30示例2:演示UDP广播发送数据的例子v设置套接字选项函数设置套接字选项函数setsockopt()vint FAR setsockopt( SOCKET s, int level, int optname, const char FAR *optval, int optlen); s:标识一个套接口的描述字
16、。 level:选项定义的层次;支持SOL_SOCKET、IPPROTO_TCP、 IPPROTO_IP、 IPPROTO_IPv6层次。 optname:需设置的选项。 optval:指针,指向存放选项值的缓冲区。optlen:optval缓冲区长度。31示例2:演示UDP广播发送数据的例子v选项设置: v让Socket发送的数据具有广播特性:BOOL bBroadcast=TRUE;setsockopt(s,SOL_SOCKET,SO_BROADCAST,(const char*)&bBroadcast,sizeof(BOOL);选项选项类型类型意义意义SO_BROADCAST BOOL允
17、许套接口传送广播信息。 32示例3v利用Socket编程实现基于UDP协议的多播通信。通信步骤:创建数据报套接字。绑定套接字于指定的地址和端口。通过套接字选项设置数据报套接字的多播属性。通过sendto()函数发送组播信息。通过recvfrom()函数接收组播消息。33示例3v利用Socket编程实现基于UDP协议的多播通信。多播地址:224.0.0.0224.0.0.255为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用;224.0.1.0224.0.1.255是公用组播地址,可以用于Internet;224.0.2.0238.255.255.255
18、为用户可用的组播地址(临时组地址),全网范围内有效;239.0.0.0239.255.255.255为本地管理组播地址,仅在特定的本地范围内有效。34示例3v利用Socket编程实现基于UDP协议的组播通信。IP多播组的加入和离开使用setsockopt()命令来完成:选项IP_ADD_MEMBERSHIP是加入组;选项IP_DROP_MEMBERSHIP是脱离组;使用套接字选项时,必须传递一个ip_mreq结构定义:struct ip_mreqstruct in_addr imr_multiaddr; /多播组struct in_addr imr_interface; /本地IP地址35示例
19、3v利用Socket编程实现基于UDP协议的组播通信。IP多播组的加入和离开使用setsockopt()命令来完成:选项IP_ADD_MEMBERSHIP是加入组: setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&ipmr, &len); 选项IP_DROP_MEMBERSHIP是脱离组: setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&ipmr, &len); 36示例3v利用Socket编程实现基于UDP协议的组播通信。多播通信的TTL(生存时间)设置:int optval = 3;setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char *)optval, sizeof(int); 多播通信的禁止回环设置:int optval = 0;setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)optval, sizeof(int);