资源描述
信息通信网络概论课程实验,东南大学自动化学院,网络编程实验,WindowsSocket编程基础知识实验一实验二、三实验四实验五、六,WindowsSocket网络编程,WindowsSocket简介套接字编程基础WindowsSocket编程原理Socket编程步骤,一、WindowsSocket的由来加利福尼亚大学伯克利分校为UNIX系统开发出了伯克利套接字(BSDsocket),在此基础上扩展形成了windows套接字。WindowsSocket规范是一套开放的、支持多协议的Windows下的网络编程接口,它规范了Internet协议族(IPS,一般为TCP/IP)的API使用.针对多样的网络协议,WindowsSocket统一了操作,简化了编程,使两个进程之间实现连接、通信。,二、windowssocket的版本WindowsSocket规范主要有两种版本即1.1和2.0版。主要区别:1.1版本只支持TCP/IP协议,2.0版本可以支持多协议三、编程时的加载事项需要包含头文件Winsock2.h,需要使用库ws2_32.lib,包含办法可以用语句来告诉编译时调用该库#pragmacomment(lib,”ws2_32.lib”);如果使用VisualC+6.0,可以通过“工程”“设置”“工程设置”“链接”“对象/库模块”中加入“ws2_32.lib”,WinSock是TCP/IP编程最低级的WindowsAPI,其代码的一部分位于Winsock32.dll中,另一部分位于Windows核心,使用WindowsAPI可以编写Internet服务器和客户端程序。应用程序调用WindowsSocket的API实现相互之间的通信(应用程序与WindowsSocket关系图),应用程序与WindowsSocket关系图,返回,操作系统为保证其安全性可靠性不允许用户直接使用,套接字有三种类型,数据报套接字(SOCK_DGRAM)一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证可靠、无差错(时序图)流式套接字(SOCK_STREAM)一种可靠的面向连接的服务,实现了无差错无重复的顺序数据传输(时序图)原始套接字(SOCK_RAW)允许对底层协议如IP或ICMP(因特网控制消息协议)直接访问,主要用于新的网络协议实现的测试等,返回,网络连接函数,基本概念,IP地址:Internet中的主机要与别的机器通信必须具有一个IP地址,IP地址是Internet中主机的标识。表示形式:常用点分形式,如202.38.64.10,最后都会转换为一个32位的整数。IP地址转换函数inet_addr()点分十进制数表示的IP地址转换为网络字节序的IP地址inet_ntoa()网络字节序的IP地址转换为点分十进制数表示的IP地址,端口号,为了区分一台主机接收到的数据包应该递交给哪个进程来进行处理,使用端口号TCP端口号与UDP端口号独立端口号一般由IANA(InternetAssignedNumbersAuthority)管理众所周知端口:11023,1255之间为大部分众所周知端口,2561023端口通常由UNIX占用注册端口:102449151动态或私有端口:4915165535,比喻:,如果把IP数据包的投递过程看成是给远方的一位朋友寄一封信,那么IP地址就是这位朋友的所在位置,如安徽合肥中国科大计算系(依靠此信息进行路由)端口号就是这位朋友的名字(依靠这个信息最终把这封信交付给这位收信者),字节序,大尾端(Big-Endian):字节的高位在内存中放在存储单元的起始位置小尾端(Little-Endian):与大尾端相反,网络字节序(NBO,NetworkByteOrder)使用统一的字节顺序,避免兼容性问题主机字节序(HBO,HostByteOrder)不同的机器HBO是不一样的,这与CPU的设计有关Motorola68K系列,HBO与NBO是一致的IntelX86系列,HBO与NBO不一致字节排序函数htonl4字节主机字节序转换为网络字节序ntohl4字节网络字节序转换为主机字节序htons2字节主机字节序转换为网络字节序ntohs2字节网络字节序转换为主机字节序,阻塞通信与非阻塞通信,阻塞方式:套接字进行I/O操作时,函数要等待到相关的操作完成以后才能返回,对提高处理机的利用率不利,但编程简单。非阻塞方式:套接字进行I/O操作时,无论操作成功与否,调用都会立即返回。阻塞方式编程简单,一个套接口的默认操作模式为阻塞,可以调用函数ioctlsocket()进行设置。,返回,面向连接的C/S网络通信程序工作流程图(TCP),返回,无连接的C/S网络通信程序工作流程图(UDP),这个bind可以是隐式的。,注意事项:,无连接的数据报传输过程中,作为服务器的一方必须先启动通信的一方可以不用bind()绑定地址和端口,由系统分配不绑定IP地址和端口号的一方必须首先向绑定地址的一方发送数据无连接客户端一般不调用connect(),在数据发送前客户与服务器各自通过socket()和bind()建立了半相关,发送数据时除指定本地套接口的地址外,还需要指定接收方套接口地址,从而在数据收发过程中动态建立全连接,返回,为了支持Windows的消息驱动机制,WinSock和BSD套接口相比有以下一些扩充:,异步选择机制异步选择函数WSAAsyncSelect()允许应用程序提名一个或多个感兴趣的网络事件,如FD_READ、FD_WRITE、FD_CONNECT、FD_ACCEPT等代表的网络事件异步请求函数异步请求函数允许应用程序用异步方式获得请求的信息,如WSAAsyncGetXByY()类函数,这些函数是对BSD标准函数的扩充。函数WSACancelAsyncRequest()允许用户终止一个正在执行的异步请求阻塞处理方法WinSock提供了“钩子函数”负责处理Windows消息,使Windows的消息循环能够继续。WinSock提供了两个函数(WSASetBlockingHool()和WSAUnhookBlockingHook()让应用程序设置或取消自己的“钩子函数”。函数WSAIsBlocking()可以检测是否阻塞,函数WSACancelBlockingCall()可以取消一个阻塞的调用错误处理WinSock提供了两个函数WSAGetLastError()和WSASetLastError()来获取和设置最近的错误号启动和终止,异步相比与同步提高了性能更具优势,不需要在接收完一个网络事件完后等待其处理完成,而可以继续接收其他网络事件。CAsyncSocket,Winsock的启动和终止应用程序在使用WindowsSocketsDll之前必须先调用启动函数WSAStartup()。该函数的功能有两个:一是由应用程序指定所要求的WindowsSocketsDll版本;二是获得系统WindowsSocketsDll的一些细节。调用终止函数WSACleanup()来终止WindowsSocketsDLL。,返回,Socket编程过程(主要讲解使用Socket的过程),使用WSAStartup()函数检查系统协议栈安装情况使用Socket()函数创建套接口socket_handle=socket(protocol_family.Socket_type,protocol);配置Socket配置一个socket需要五种信息:本地和远地机的IP地址本地和远地进程的协议端口连接所使用的协议使用Socket发送或接收数据使用send或sendto方法发送数据,recv或recvfrom方法接收数据。使用WSACleanup()函数关闭与WindowsSocketsDLL的连接,返回,实验一,实验内容:使用Socket函数编写一个小程序实现查询主机地址即输入IP地址能够给出该IP地址对应的域名;给出域名可以给出IP地址。实验要求:理解掌握WSAStartup()、WSACleanup()函数的使用;知道WSADATA、HOSTENT结构成员表示意义和inet_ntoa()、inet_addr()函数的使用。主要步骤:1、网络程序初始化,调用其它WinSock函数之前先使用WSAStartup()函数初始化2、通过WinSock发送和接收数据3、程序结束必须关闭Socket,使用WSACleanup()释放所分配的内部缓冲区和其他资源。,记录主机信息,包括主机名、别名、地址类型、地址列表等。,IP地址的点分十进制字符串(如4.3.2.16)与IN_ADDR结构体之间的相互转化,intWSAStartup(WORDwVersionRequested,LPWSADATAlpWSAData);,函数说明:wVersionRequested是应用程序对WindowsSocketsDLL版本要求。高字节代表次版本号,低字节代表主版本号。如定义wVersionRequested0 x0002,则表示应用程序对DLL的最低要求为2.0版本lpWSAData用于返回WindowsSocketsDLL的一些技术细节,是指向WSAData结构的一个指针。其中WSAData的成员变量wHighVersion指明DLL支持的最高版本,成员变量wVersion代表wHighVersion与wVersionRequested的最小值,也就是DLL希望用户使用的版本号函数调用成功,返回值0;若失败,则返回错误码,可用WSAGetLastError()查看下面举例说明函数的使用,WindowsSocketsDLL的初始化过程WORDwVersionRequested;WSADATAwsaData;Interr;wVersionRequested=0 x0002;Err=WSAStartup(wVersionRequested,/*协商成功,启动了DLL*/,实验一界面样例,返回,实验二、三,实验内容:编写一个连接FTP程序,实现检索FTP文件服务器、上传文件、下载文件。理解FTP协议是非对称的协议。实验要求:理解掌握CInternetSession()、GetFtpConnection()、CFtpFileFind()、GetFile()、PutFile()、FindNextFile()函数的使用,类、函数表单:,主要步骤:,1、创建一个INTERNET会话(CInternetSession())2、建立与FTP服务器的连接CFtpConnection对象如果连接成功,获得当前登陆的缺省目录下所有的文件和目录名称,即如何检索某一个目录下的文件,并显示文件信息3、下载文件或上传文件4、关闭连接举例说明一下一些函数的使用,CInternetSessionsess(_T(“MyProgram/1.0”);/建立会话CFtpConnection*pConnect=NULL;try/需要进行异常处理/建立ftp连接pConnect=sess.GetFtpConnection(_T();/创建CFtpFileFind对象/利用函数FindFile()以及FindNextFile()查找并显示所有文件CFtpFileFindfinder(pConnect);BOOLbWorking=finder.FindFile(_T(*);while(bWorking)bWorking=finder.FindNextFile();printf(%sn,(LPCTSTR)finder.GetFileURL();catch(CInternetException*pEx)/注意异常类型TCHARsz1024;pEx-GetErrorMessage(sz,1024);printf(ERROR!%sn,sz);pEx-Delete();,实验二界面样例,返回,实验四:聊天工具,实验目的实验内容及要求实验步骤注意事项,实验目的,在前面两个实验的基础上进一步了解网络编程的过程。掌握Windows环境下基于WinSock的编程方法和通讯实现。编写一个聊天程序,即以客户端和服务器的模式进行互发消息。,back,实验内容及要求,利用MFC中的CAsyncsocket类已经集成了socket的基本函数,我们可以直接使用其成员函数来建立,初始化并应用socket,利用客户端和服务器模式,编写一个点对点的,可以相互发送和接收消息的程序,也就是常说的聊天工具。该工具具有既可以作为服务器也可以做为客户端使用。当作为服务器时要具有能输入自己的IP值和端口值,并能进行在线监听是否有客户端要求连接,如果有,还要能进行适当的响应,也就是接受连接请求建立连接,并实现消息互发。当作为客户端是,要求能输入远地服务器的IP值和端口数,并进行连接请求,等待远地服务器的响应,当连接上后要能与服务器进行互发消息,聊天结束后还要实现与服务器的断开的功能。,back,实验步骤(1),建立自己的socket类使用MFC中的CAsyncsocket类作为基类重载虚拟函数建立自己的socket类。Eg.:classCMySocket:publicCAsyncSocket然后重载函数voidCMySocket:OnAccept()voidCMySocket:OnClose()voidCMySocket:OnConnect()voidCMySocket:OnReceive()这些函数系统会在有网络消息的时候自动调用它们,在下面的实验步骤(2)中提到要使用的函数就是在这些重载函数中调用的。(例子)我们还可以在这些函数中加入自己的代码,实现自己想要得功能。最后还要在这个类中加入一个指向对话框类的指针作为成员变量,我们就是利用这个对话框类的成员函数来重载上面的虚拟函数的。,实验步骤(2),使用的函数服务器端:建立Socket:调用成员函数Socket()函数绑定端口:调用成员函数bind()函数(注:对于MFC编程我们只要调用Create()函数就可以包括上面的两个函数)监听:调用成员函数listen()函数服务器端接受客户端的连接请求:调用成员函数accept()函数结束socket连接:调用成员函数closesocket()客户端:建立客户端的Socket:调用socket()函数(注:我们也是调用Create()函数来完成Socket的建立的)提出连接申请:调用成员函数connect()函数以上这些函数我们是在重载前面的虚拟函数时使用的,例如OnAccept()函数中调用accept()函数等等。,实验步骤(3),制作界面对话框类使用的控件:Listbox,用于显示已发出和已接收的消息。Combobox(orRadiobutton),用于模式选择,客户机或服务器。Editbox,用于输入IP和端口。Button,控制命令按钮。注意:要在对话框类中添加两个我们自己的socket类作为成员变量。因为当作为服务器时要有两个套接字。一个用于侦听连接请求,一个用于被连接到另一个应用程序。当然作为客户机时只要一个套接字就可以了。界面例子,back,注意事项(1),两个MFC函数BOOLAfxSocketInit(WSADATA*lpwsaData=NULL);这个函数中调用:WSAStartup在你的程序退出的时候自动调用:WSACleanupintWSAAsyncSelect(SOCKETs,HWNDhWnd,unsignedintwMsg,longlEvent);当有网络事件发生时系统会通知窗口并调用对应的函数。我们要做的就是重载这些回调函数,加入我们要的指令实现我们要的功能。,创建工程时别忘了CWinApp:InitInstance()函数中调用这个函数来初始化,注意事项(2),消息发送函数intSend(constvoid*lpBuf,intnBufLen,intnFlags=0);在使用这个函数之前要先判断消息发送编辑框是否有消息,如果是空则不发送,用CString.IsEmpty()函数进行判断,当不为空的时候返回0,否则返回非0。当发送函数调用成功时返回发送数据的长度,否则返回SOCKET_ERROR.消息接受函数Receive(void*lpBuf,intnBufLen,intnFlags=0);当该函数调用成功时返回接收到的数据的长度,否则返回SOCKET_ERROR。我们可以事先分配一个大小为1025的数组用来缓存接收数据,当接收成功后要在这个数组最后加上NULL,即字符串的结束符,并将之转化为字符串类型,然后就可以使之在列表框中显示了。,注意事项(3),实现控件的禁用和启用函数EnableWindow(TRUE/FALSE),这个函数在我们这个实验中经常用到,使用这个函数我们就可以实现当程序在某种状态下禁止一些不相关的控件的使用,这样就可以避免用户的一些不必要的误操作。,back,back,back,back,back,back,实验五、六:设计协议,实验内容:在Windows网络环境下,以其中的2台计算机为对象,构成主从计算机应用系统,设计简单的应用层协议,开发基于TCP/IP或UDP/IP的网络通信程序,实现数据传送和文件传输。实验要求:正确理解应用层协议的概念;更深入了解客户/服务器模式的网络编程设计。实验步骤及所需函数:参考实验二、三、四。,基于TCP的SOCKET编程,服务器端1:创建套接字(socket)2:将套接字绑定到一个本地地址和端口上(bind)3:将套接字设为监听模式,准备接受客户请求(listen)4:等待客户请求到来;请求到来后,接受请求,返回一个新的对应于此次连接的套接字(accept)5:用返回的套接字和客户端进行通信(send/recv)6:返回,等待另一客户请求7:关闭套接字,客户端1:创建套接字(socket)2:向服务器发出连接请求(connect)3:和服务器进行通信(send/recv)4:关闭套接字,基于UDP的socket编程,服务器端1:创建套接字(socket)2:将套接字绑定到一个本地地址和端口上(bind)3:等待接收数据(recvfrom)4:关闭套接字,客户端1.创建套接字(socket)2.向服务器发送数据(sendto)3.关闭套接字,Thankyou!,
展开阅读全文