




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、2015.9.21曹亚帅UDP_WINSOCK三枚铜钱工作室2015.9.21UDP用最通俗的话讲,所谓UDP,就是发送出去就不管的一种网络协议。因此UDP编程的发送端只管发送就可以了,不用检查网络连接状态。下面用例子来说明怎样编写UDP,并会详细解释每个API和数据类型。2015.9.21UDP协议模式2015.9.21【原创分享】Win32Socket简单示例用简单的代码和演示说明了WinSocket的使用一般必要步骤。先看看程序执行的效果吧:2015.9.21最上面的一个窗口为服务端,下面的窗口为客户端;服务端的主循环负责接收数据。如果客户端输出“exit/quit”字符串的话,则服务端
2、和客户端程序终止。这个示例主要是通过简单的代码让初学者了解到WSA(WinSocketAPI)的启动相关的函数和参数,以及收发相关的两个函数的使用,最后释放WS资源。可以理解为一个最小的C/S演示。2015.9.21对于聊天程序来说,即使丢失一些数据,也不会影响信息的交流,可以根据上下文的情况,知道对方所要表达的意思,或者根据对方的信息,重新发送我们所说的话。对于TCP来说,在通信前,需要经过三步握手协议以建立连接,而建立过程往往是比较消耗时间的。建立连接后,在聊天过程中,可能经过好长一段时间,双方才会说一句话,那么连接应该保持还是应先断开,等对方说话时再建立呢?也就是说,TCP协议的面向连接
3、、数据确认和重传机制将会影响聊天的效率。所以对于聊天类的软件来说,通常都采用基于UDP的方式来实现。其特点就是不需要建立连接,也没有数据确认和重传机制,因此适时性较高。2015.9.21本示例的基本实现过程是:客户端通过键盘输入数据,数据被发送到服务器。后者接收到数据后,需要进行判断,如果发来的数据串为quit,表明对方向退出聊天过程,于是服务器端也发送字符串quit,聊天过程终止;否则将接收到的信息和对方的IP地址进行格式化后,在屏幕上输出。同样在客户端也需要进行相应的判断和输出。2015.9.21TCP协议模式2015.9.21UDP网络程序编写基于UDP(面向无连接)的socket编程服
4、务器(接收端)程序1.创建套接字(socket)2.将套接字绑定到一个本地地址和端口上(bind)3.等待接收数据(recvfrom)4.关闭套接字客户端(发送端)程序1.创建套接字(socket)2.向服务器端发送数据(sendto)3.关闭套接字2015.9.21服务端:2015.9.21/*ChatServerCPP*/#pragmacomment(lib,ws2_32.lib)/winsocket2需要的库文件#include/winsocket2的头文件(对于Winsock2.0应包括Winsock2.h文件)#include2015.9.21WSADATA类型是一个结构,描述了So
5、cket库的一些相关信息,其结构定义如下:typedefstructWSADataWORDwVersion;WORDwHighVersion;charszDescriptionWSADESCRIPTION_LEN+1;charszSystemStatusWSASYS_STATUS_LEN+1;unsignedshortiMaxSockets;unsignedshortiMaxUdpDg;charFAR*lpVendorInfo;WSADATA;wVersionRequested=MAKEWORD(2,0);注意低位内存存储主版本号2,高位内存存储副版本号0,其值为0 x0002。使用宏LOBY
6、TE可以读取WORD的低位字节,HIBYTE可以读取高位字节。2015.9.21voidmain()/*第一步:初始化WINSOCK*/WORDwVersionRequested;/应用程序所需的Winsock版本号WSADATAwsaData;/用来返回Winsock实现的细节信息interr;/出错代码wVersionRequested=MAKEWORD(1,1);/生成版本号1.1err=WSAStartup(wVersionRequested,&wsaData);/调用初始化函数if(err!=0)return;/通知用户找不到合适的DLL文件返回值为零的时候是表示成功申请WSASta
7、rtup2015.9.21/确认返回的版本号是客户要求的1.1;否则的话,调用WSACleanup()清除信息,结束函数if(LOBYTE(wsaData.wVersion)!=1|HIBYTE(wsaData.wVersion)!=1)WSACleanup();/调用函数解除与Winsock.DLL库的绑定,释放Winsock实现分配给应用程序的系统资源,中止对WindowsSocketsDLL的使用return;/至此,可以确认初始化成功,Winsock.DLL可用;如果不是1.1的则退出/*第二步:创建套接口;建立一个socket*/SOCKETsockSrv=socket(AF_INE
8、T,SOCK_DGRAM,0);/创建一个数据报套接字;AF_INET是IPV4的标志;SOCK_DGRAM是UDP数据包的标志;创建socket服务,使用udp协议2015.9.21专门针对Internet通信域的Winsock地址结构structsockaddr_inshort.sin_family;/指定地址家族,一定是AF_INET.u_shortsin_port;/指定将要分配给套接字的传输层端口号structin_addrsin_addr;/指定套接字的主机的IP地址charsin_zero8;/全置为0,是一个填充数WinsockAPI特为此设置了四个函数(1)htonl()将主
9、机的无符号长整型数本机顺序转换为网络字节顺序(HosttoNetworkLong),用于IP地址。u_longPASCALFARhtonl(u_longhostlong);hostlong是主机字节顺序表达的32位数。htonl()返回一个网络字节顺序的值。2015.9.21/*第三步:填充sockaddr_in结构*/SOCKADDR_INaddrSrv;/定义一个Sockaddr_in型的结构实例变量/指定套接字的主机的IP地址;一台机器可以用很多个IP,也可以制定为INADDR_ANY,这样会对所有有效IP都适用addrSrv.sin_addr.S_un.S_addr=htonl(INA
10、DDR_ANY);/服务器绑定的IP是任意的;转换Unsignedshort为网络字节序的格式addrSrv.sin_family=AF_INET;/指定地址家族,一定是AF_INET;指定通信域是InternetaddrSrv.sin_port=htons(7000);/指定将要分配给套接字的传输层端口号;指定端口,将端口号转换为网络字节顺序2015.9.21在使用Internet域的套接字时,这三个数据结构的一般用法是:首先,定义一个Sockaddr_in的结构实例变量,并将它清零。然后,为这个结构的各成员变量赋值;第三步,在调用BIND()绑定函数时,将指向这个结构的指针强制转换为soc
11、kaddr*类型。2015.9.21/*第四步:将套接口绑定到指定的网络地址BIND()*/开始绑定这个服务器,用创建好的SOCKET对象和服务器IP信息、以及服务器IP信息的长度;将套接字绑定到一个本地地址和端口上(bind)bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR);/第二参数要强制类型转换;将套接字绑定到指定的网络地址,对&addrSrv进行了强制类型转换/*第五步:接收数据*/申请变量charrecvBuf100;/接收数据包charsendBuf100;/发送数据包chartempBuf200;/临时存储区SOCKADDR_IN
12、addrClient;intlen=sizeof(SOCKADDR);/sockaddr结构的长度;初始化这个参数,这个参数必须被初始化2015.9.21while(1)/不断等待客户端请求的到来/从客户端接收应答消息;接受数据到recvBuf100recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);/如果接收的应答字符串为“quit”,则告知对方对话结束if(!strcmp(quit,recvBuf)/向客户端提交字符串数据包sendto(sockSrv,quit,strlen(quit)+1,0,(SOCKADDR*)&a
13、ddrClient,len);printf(Chatend!n);break;2015.9.21sprintf(tempBuf,%ssay:%s,inet_ntoa(addrSrv.sin_addr),recvBuf);/将sin_addr储存的IP(数值)转换成字符串形式(127.0.0.1)。2015.9.21/打印出对方聊天的IP和聊天内容sprintf(tempBuf,%ssay:%sn,inet_ntoa(addrClient.sin_addr),recvBuf);printf(“%sn,tempBuf);/如果不是Q则将客户端的IP地址和发送的数据格式化完放到tempBUf中pri
14、ntf(“请输入对话:n);gets(sendBuf);/从标准输入流中获取一行数据sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrClient,len);/将用户输入的数据发送到客户端;向客户端提交字符串数据包/*第六步:关闭socket,释放网络*/closesocket(sockSrv);WSACleanup();2015.9.21客户端:2015.9.21/*ChatClientCPP*/#pragmacomment(lib,ws2_32.lib)#include#include2015.9.21voidmain()
15、/加载socket动态链接库(dll)WORDwVersionRequested;WSADATAwsaData;/这结构是用于接收WindowsSocket的结构信息的interr;wVersionRequested=MAKEWORD(1,1);/请求1.1版本的WinSock库err=WSAStartup(wVersionRequested,&wsaData);if(err!=0)return;/返回值为零的时候是表示成功申请WSAStartup/*第一步:初始化WINSOCK*/2015.9.21if(LOBYTE(wsaData.wVersion)!=1|HIBYTE(wsaData.w
16、Version)!=1)WSACleanup();return;/检查这个低字节是不是1,高字节是不是1以确定是否我们所请求的1.1版本/否则的话,调用WSACleanup()清除信息,结束函数2015.9.21SOCKADDR_INaddrSrv;/初始化SOCKADDR_IN,IP,端口addrSrv.sin_addr.S_un.S_addr=inet_addr(“127.0.0.1”);/本地回路地址是127.0.0.1;设置要连接的主机IP,这里用一台机做试验addrSrv.sin_family=AF_INET;addrSrv.sin_port=htons(7000);/*第二步:创建
17、套接口;建立一个socket*/SOCKETsockClient=socket(AF_INET,SOCK_DGRAM,0);/*第三步:填充sockaddr_in结构*/2015.9.21/*第五步:接收数据*/申请变量charrecvBuf100;charsendBuf100;chartempBuf200;intlen=sizeof(SOCKADDR);2015.9.218按照指定目的地向数据报套接字发送数据SENDTO()intsendto(SOCKETs,char*buf,intlen,intflags,structsockaddr*to,inttolen);9接收一个数据报并保存源地址
18、,从数据报套接字接收数据RECVFORM()intrecvfrom(SOCKETs,char*buf,intlen,intflags,structsockaddr*from,int*fromlen);10关闭套接字CLOSESOCKET()intclosesocket(SOCKETs);2015.9.21while(1)/客户端循环接收;发送数据printf(“请输入对话:n);gets(sendBuf);/用户输入一串字符串/向服务器端发送消息sendto(sockClient,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrSrv,len);recv
19、from(sockClient,recvBuf,100,0,(SOCKADDR*)&addrSrv,&len);/接受数据到recvBuf1002015.9.21if(!strcmp(quit,recvBuf)/如果接收的应答字符串为“quit”,则告知对方对话结束sendto(sockClient,quit,strlen(quit)+1,0,(SOCKADDR*)&addrSrv,len);printf(Chatend!n);break;2015.9.21/客户端显示发送内容sprintf(tempBuf,%ssay:%sn,inet_ntoa(addrSrv.sin_addr),recvBuf);printf(%sn,tempBuf);closesocket(sockClient);WSACleanup();/终止对套接字库的使用2015.9.21就这么简单,一个简化的网络程序就写出来了。当然要完成完备的网络通信软件或者其他网络应用软件要比这个复杂,但是这也是通向复杂的开始。很多朋友接触网络编程的时候,感到很痛苦,因为可能一开始看得程序示例实现的功能比较全面,代码量一大反而可能不便于理解,这也是很多人一开始在学网络编程时畏惧网络编程的原因吧。2015.9.21这里面涉及到的WSA(WinSocketAPI)函数就是如下几个:WSAStartup()socket()bi
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 北京小工装合同范本
- 净水渔业合同范本
- 专柜撤柜合同范本
- 冷库轨道转让合同范本
- 借购合同范例范例
- 出租给超市合同范本
- 鲜花店采购合同范本
- 品牌授权合作合同范本
- 租赁奢华汽车合同范本
- 合伙开模合同范本
- 生物节律调节课件
- 2025年黑龙江民族职业学院单招职业技能测试题库汇编
- 感恩父母课件:父母的爱如山如水
- 不分手承诺书(2025版)恋爱忠诚协议
- 2020-2025年中国国有控股公司行业发展趋势及投资前景预测报告
- 病区8S管理成果汇报
- 民法典题库(附答案)
- 绥芬河市2025年上半年招考事业单位专业人员易考易错模拟试题(共500题)试卷后附参考答案
- 小学数学新课程标准(教育部2024年制订)
- 2025复工复产安全教育培训
- 2024年叉车司机车辆基本操作知识考试题库及答案(共70题)
评论
0/150
提交评论