SUP-3-Socket编程基础

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

WindowsSDKSUP-3Socket编程基础课程描述在开发网络应用程序时,最重要的问题就是如何实现不同主机之间的通信。在TCP/IP网络环境中,可以使用Socket接口来建立网络连接、实现主机之间的数据传输。本章将介绍使用Socket接口来编写网络应用程序的基本方法。本章知识点Socket协议原理WinSock编程基础面向连接的Socket编程面向非连接的Socket编程套接字选项SUP-3.1Socket协议原理SUP-3.1.1Socket协议的工作原理SUP-3.1.2Socket的服务方式和类型SUP-3.1.1Socket协议的工作原理在网络应用程序中,实现网络通信的必要条件:(1)拨打电话的一方需要知道对方的电话号码。如果对方使用的是内部电话,则还需要知道分机号码。而被拨打的电话则不需要知道对方的号码。(2)被拨打的电话号码必须已经启用,而且将电话线连接到电话机上。(3)被拨打电话的主人有空闲时间可以接听电话,如果长期无人接听,则会自动挂断电话。(4)双方必须使用相同的语言进行通话。这一条看似有些多余,但如果真的一个说汉语、另一个却说英语,那也是没有办法正常沟通的。(5)在通话过程中,物理线路必须保持通畅,否则电话将会被挂断。(6)在通话过程中,任何一方都可以主动挂断电话。基于TCP协议的两个网络应用程序进行通信的基本过程(1)客户端(相当于拨打电话的一方)需要了解服务器的地址(相当于电话号码)。在TCP/IP网络环境中,可以使用IP地址来标识一个主机。但仅仅使用IP地址是不够的,如果一台主机中运行了多个网络应用程序,那么如何确定与哪个应用程序通信呢。在Socket通信过程中借用了TCP和UDP协议中端口的概念,不同的应用程序可以使用不同的端口进行通信,这样一个主机上就可以同时有多个应用程序进行网络通信了。这有些类似于电话分机的作用。(2)服务器应用程序必须早于客户端应用程序启动,并在指定的IP地址和端口上执行监听操作。如果该端口被其他应用程序所占用,则服务器应用程序无法正常启动。服务器处于监听状态就类似于电话接通电话线、等待拨打的状态。(3)客户端在申请发送数据时,服务器端应用程序必须有足够的时间响应才能进行正常通信。否则,就好像电话已经响了,但却无人接听一样。在通常情况下,服务器应用程序都需要具备同时处理多个客户端请求的能力,如果服务器应用程序设计得不合理或者客户端的访问量过大,都有可能导致无法及时响应客户端的情况。(4)使用Socket协议进行通信的双方还必须使用相同的通信协议,Socket支持的底层通信协议包括TCP和UDP两种。在通信过程中,双方还必须采用相同的字符编码格式,而且按照双方约定的方式进行通信。这就好像在通电话的时候双方都采用对方能理解的语言进行沟通一样。(5)在通信过程中,物理网络必须保持畅通,否则通信将会中断。(6)通信结束后,服务器端和客户端应用程序都可以中断它们之间的连接。Socket编程的层次结构SUP-3.1.2Socket的服务方式和类型在Socket通信中,套接字分为3种类型,即流式套接字(SOCK_STREAM)、数据报式套接字(SOCK_DGRAM)和原始套接字(SOCK_RAW)。1.流式套接字流式套接字提供面向连接的、可靠的数据传输服务,可以无差错地发送数据。传输数据可以是双向的字节流,即应用程序采用全双工方式,通过套接字同时传输和接收数据。应用程序可以通过流传递有序的、不重复的数据。所谓“有序”指数据包按发送顺序送达目的地址,所谓“不重复”指一个特定的数据包只能获取一次。如果必须保证数据能够可靠地传送到目的地、并且数据量很大时,可以采用流式套接字传输数据。文件传输协议(FTP)即采用流式套接字传输数据。2.数据报式套接字比较项目流式套接字数据报式套接字建立和释放连接√×保证数据到达√×按发送顺序接收数据√×通讯数据包含完整的目的地址信息×√3.原始套接字原始套接字是公开的套接字编程接口,使用它可以在IP层上对套接字进行编程,发送和接收IP层上的原始数据包,例如ICMP、TCP和UDP等协议的数据包。SUP-3.2WinSock编程基础SUP-3.2.1构建WinSock应用程序框架SUP-3.2.2IP地址的表示形式SUP-3.2.1构建WinSock应用程序框架WinSock包含两个主要的版本,即WinSock1和WinSock2。在使用WinSock1.1时,需要引用头文件winsock.h和库文件wsock32.lib,代码如下:#includewinsock.h#pragmacomment(lib,wsock32.lib)在VisualStudio2005中,通常使用WinSock2.2实现网络通信的功能,则需要引用头文件winsock2.h和库文件ws2_32.lib,代码如下:#includewinsock2.h#pragmacomment(lib,ws2_32.lib)使用WinSock2.2实现网络通信的应用程序框架#includewinsock2.h#pragmacomment(lib,ws2_32.lib)//主函数int_tmain(intargc,_TCHAR*argv[]){//WSADATA结构体主要包含了系统所支持的Winsock版本信息WSADATAwsaData;//初始化Winsock2.2if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0){printf(WSAStartup无法初始化!);return0;}//使用WinSock实现网络通信//......//最后应该做一些清除工作if(WSACleanup()==SOCKET_ERROR)printf(WSACleanup出错!);return0;}结构体WSADATA用于存储调用WSAStartup()函数后返回的WindowsSocket数据。typedefstructWSAData{WORDwVersion;WORDwHighVersion;#ifdef_WIN64unsignedshortiMaxSockets;unsignedshortiMaxUdpDg;charFAR*lpVendorInfo;charszDescription[WSADESCRIPTION_LEN+1];charszSystemStatus[WSASYS_STATUS_LEN+1];#elsecharszDescription[WSADESCRIPTION_LEN+1];charszSystemStatus[WSASYS_STATUS_LEN+1];unsignedshortiMaxSockets;unsignedshortiMaxUdpDg;charFAR*lpVendorInfo;#endif}WSADATA,FAR*LPWSADATA;结构体WSADATA的各字段说明字段含义wVersionWindowsSocketsDLL期望调用者使用的WindowsSockets规范的版本,为WORD类型。高位字节中存储副版本号,低位字节中存储高版本号。可以使用MAKEWORD()函数返回该值,例如MAKEWORD(2,2)wHighVersionWindowsSocketsDLL可以支持的WindowsSockets规范的最高版本szDescription以null结尾的ASCII字符串。WindowsSocketsDLL将对WindowsSockets实现的描述复制到该字符串中,最多可以包含256个字符szSystemStatus以null结尾的ASCII字符串。WindowsSocketsDLL将有关状态或配置信息复制到该字符串中iMaxSockets单个进程可以打开的最大套接口数量。WindowsSockets可以提供一个全局的套接口,为每个进程分配套接口资源。程序员可以使用该多好数字作为WindowsSockets是否可以被应用程序使用的原始依据iMaxUdpDgWindowsSockets应用程序能够发送或接收的最大UDP数据包大小,单位为字节。如果实现方式没有限制,则iMaxUdpDg等于0lpVendorInfo指向销售商数据结构的指针WSAStartup()函数intWSAStartup(INWORDwVersionRequested,OUTLPWSADATAlpWSAData);参数说明如下:wVersionRequested,WindowsSocketsDLL规定调用者可以使用的WindowsSockets规范的版本,为WORD类型。高位字节中存储副版本号,低位字节中存储高版本号。可以使用MAKEWORD()函数返回该值,例如MAKEWORD(2,2)。lpWSAData,指向WSADATA结构体的指针,用于接收WindowsSockets执行的数据。【例SUP-3.1】通过一个控制台应用程序实例来演示初始化WindowsSockets并返回结果的方法。假定项目名称为WSAStartup,主程序WSAStartup.cpp的代码如下:#includestdafx.h#includewinsock2.h#pragmacomment(lib,ws2_32.lib)#includestdlib.hint_tmain(intargc,_TCHAR*argv[]){//WSADATA结构体主要包含了系统所支持的Winsock版本信息WSADATAwsaData;//初始化Winsock2.2if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0){printf(WSAStartup无法初始化!);return0;}//显示wsaData中的数据printf(Version:%d.%d\n,LOBYTE(wsaData.wVersion),HIBYTE(wsaData.wVersion));printf(HighVersion:%d.%d\n,LOBYTE(wsaData.wHighVersion),HIBYTE(wsaData.wHighVersion));printf(Description:%s\n,wsaData.szDescription);printf(SystemStatus:%s,wsaData.szSystemStatus);//最后应该做一些清除工作if(WSACleanup()==SOCKET_ERROR)printf(WSACleanup出错!);printf(\n\n);system(pause);return0;}例SUP-3.1SUP-3.2.2IP地址的表示形式对于网络管理员或普通用户而言,IP地址常用点分法来表示。即使用4个0~255的整数表示IP地址,每个整数之间使用小数点(.)分隔,例如192.168.0.1。在第3章中已经对IP地址的这种表示形式做了详细的介绍。但是在计算机中并不使用点分法来保存IP地址,因为这样会浪费存储空间,而且不便于根据IP地址和子网掩码计算子网的信息。事实上,在计算机中使用无符号长整数(unsignedlong)来存储和表示IP地址,而且分为网络字节顺序(NBO,NetworkByteOrder)和主机字节顺序(HBO,HostByteOrder)两种格式。在网络程序设计时必须了解IP地址的这两种表示形式。1.网络字节顺序格式在网络传输过程中,IP地址被保存为32位二进制数。TCP/IP协议规定,在低位存储地址中保存数据的高位字节,这种存储顺序格式被称为网络字节顺序。数据按照32位二进制数为一组进行传输,因为采用网络字节顺序,所以数据的传输顺序是由高位至低位进行的。在VisualC++中使用结构体in_addr来保存网络字节顺序格式的IP地址,它的定义代码如下:structin_addr{union{struct{u_chars_b1,s_b2,s_b3,s_b4;}S_un_b;struct{

1 / 103
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功