1、实验十七Winsock编程 作者: 日期:12 个人收集整理 勿做商业用途实验十七 Winsock编程【实验目的】 (1)熟悉Visual C+的基本操作。 (2)基本了解基于对话框的windows应用程序的编写过程. (3)对于Windows Socket编程建立初步概念。【实验要求】 (1)应用VisualC+中MFCCSocket类,实现网络数据传输。 (2)制作实用的局域网数据传输程序。【实验原理】一、Windows Socket和套接口的基本概念 网际协议(Intemet Protocol,IP)是一种用于互联网的网络协议,已广为人知。它可广泛用于大多数计算机操作系统上,也可用于大多
2、数局域网LAN(比如办公室小型网络)和广域网WAN(比如说互联网)。从它的设计看来,它是一个无连接的协议,并不能保证数据投递万无一失。两个上层协议(TCP和UDP)依赖IP协议进行数据通信.如果希望在Microsoft Windows下通过TCP和UDP协议建立网络应用程序,则需要使用Winsock套接口编程技术。套接口,就是一个指向传输提供者的句柄。Win32中,套接口不同于文件描述符,所以它是一个独立的类型SOCKET。Windows Sockets描述定义了一个Microsoft Windows的网络编程界面,它是从Unix Socket的基础上发展而来的,为Windows TCPIP提
3、供了一个BSD型的套接字规范,除与43BSD Unix Sockets完全兼容外,还包括一个扩充文件,通过一组附加的API实现Windows式(即事件驱动)的编程风格;而Winsock则是在MicrosoftWindows中进行网络应用程序设计的接口。Windows在Internet支配域中的TCPIP协议定义了Winsock网络编程规范,融入了许多新特点.使用Socket的目的是使用户在网络协议上工作而不必对该网络协议有非常深入的了解。此外,编写的程序还可被迅速地移植到任何支持Socket的网络系统中去。 Winsock提供了二种可为指定传输协议打开、计算和关闭会话的能力。在Windows下
4、,TCPIP上层模型在很大程度上与用户的Winsock应用有关:换言之,用户的Wimock应用控制了会话的方方面面,必要时,还会根据程序的需要格式化数据。 套接口有三种类型:流式套接口、数据报套接口及原始套接口。 流式套接口定义了一种可靠的面向连接的服务(利用TCP协议),实现了无差错无重复的顺序数据传输。数据报套接口定义了一种无连接的服务(UDP协议),数据通过相互独立的报文进行传输,是无序的,并且不保证可靠和无差错。原始套接口允许对低层协议如IP或ICMP直接访问,主要用于新的网络协议实现的测试等. 面向连接服务器处理的请求往往比较复杂,不是一来一去的请求应答所能解决的,而且往往是并发服务
5、器。使用面向连接的套接口编程,可以通过图来表示。无连接服务器一般都是面向事务处理的,一个请求、一个应答就完成了客户程序与服务程序之间的相互作用.若使用无连接的套接口编程,程序的流程可以用图表示.套接口工作过程如下:服务器首先启动,通过调用socket()建立一个套接口,然后调用bind()将该套接口和本地网络地址联系在一起,再调用listen()使套接口做好侦听的准备,并规定它的请求队列的长度,之后,调用accept()来接收连接。客户在建立套接口后就可调用conllet()和服务器建立连接。连接一旦建立,客户机和服务器之间就可以通过调用read()和write()来发送和接收数据.最后,待数
6、据传送结束后,双方调用close()关闭套接口。 在网络编程中,掌握端口的概念十分重要. 端口:基于TCPIP协议的网络中,计算机都分配有一个IP地址,用一个32位二进制数来表示,正式的称呼是“Ipv4地址.客户机需要通过TCP或UDP和服务器通信时,必须指定服务器的IP,地址和服务端口号.另外,服务器打算侦听接入客户机请求时,也必须指定一个IP,地址和一个端口号。在选择端口时,应特别小心,因为有些可用端口号是为“已知的”(即固定的)服务保留的,如文件传输协议和超文本传输协议,即FTP(21号端口)和HTTP(一般为8080端口)。“已知的协议,即固定协议,采用的端口由“互联网编号分配认证(I
7、ANA)”控制和分配,RFC 1700中说明的编号。 从本质上说,端口号可分成3类:“已知”端口、已注册端口、动态和(或)私用端口。 (1)“已知”端口0-1023,由IANA控制,是在UNIX中为固定服务保留的。 (2)已注册的端口102449151,由IANA列出来的,供普通用户的普通用户进程或程序使用。 (3)动态和(或)私用端口49152-65535。 普通用户应用应选择1024-49151之间的已注册端口,从而避免端口号已被另一个应用或系统服务所用.此外,49152-65535间的端口可自由使用,因为IANA这些端口上没有注册服务。二、MFC CSocket类的通信流程使用CSock
8、ct类进行网络二进制数据通信的连接流程,如下表所示。 服务器端 注释 客 户 端lCsocket m_server构造一个socket对象Csocket m_client2m_server。create(nport)创建socketM_client。create(nport)3m_server。listen()听等连接与服务器建立连接m_client。connectstraddr,nport)此时阻塞。等待服务器端侦听.4Csocket m_receive;m_server。accpet(m_receive)此时阻塞,等待客户机连接构造新的socket对象用以接收客户端的连接5CsocketF
9、ile file(&m_server);构造一文件对象CsocketFile file(m_server)6CArchivearin(file,CArchive::load)CArchivearout(file,CArchive:store)构造流对象CArchivearin(&file,CArchive::Ioad)CArchivearout(file,CArchive:store)7arinvalue;aroutvalue;用流进行数据的传输概念和cin,cout相似arinvalue;aroutm_pMainWnd))-ShowAcccpt(); /这里仅仅添加了这一句,因为CLx2DI
10、g类是发送接收消息的主窗口, /而且应用程序发送接收的消息也在CLx2Dlg对象实例中进行, /所以当CServer类的对象收到客户机的Connect消息时,/便可调用CLx2DLg对象中的ShowAccept()函数处理。该步完成以后,可以为CLx2DIg类添加public成员函数ShowAccept(): void CLx2Dlg::ShowAccept() m_server。Accept(m_recv); AfxMessageBox(”Server端连接成功”); m_send。EnableWindow(TRUE); /连接成功,可以发送 m_listen.EnableWindow(FA
11、T SE); /同时禁止侦听按钮 于是,当客户机调用m_client.Connect(m_ip,1000);时,主机server端发现并调用ShowAccept函数来建立连接。执行完以后,Socket连接便被建立。 接下来的工作便是添加发送聊天信息的函数了. 注意到前面点击发送按钮的OnSend()函数已经添加好了,在Lx2工程中只要添加Server端的接收消息和显示消息功能就可以进行消息的传送. 在CServer类中像添加OnAccept()一样添加成员函数OnReceive(): void Cserver::OnReceive(int nErrorCode) / TODO:Add your
12、 specialized code here and/or call the base class CSoeket::OnReceive(nErrorCode): ((CLx2DIg*)(AfxGetApp()-m_pMainWnd)-ShowMsg(); 建立连接后,一方一旦发送数据,另一方的CSocket派生类便调用该函数.其中代码可以参考前面OnAccept()进行理解. 在CLx2DIg里添加成员函数ShowMsg(): void CLx2Dlg::ShowMsg() charbuff255;m_reev.Receive(buf,255); /接收消息到buf里面,长度255字节CSt
13、ring msg;Msg。Format(”s”,buf);AfxMessageBox(msg); /用AfxMessageBox函数显示接收到的字符串 /这里注意CString类的用法 同样地,逐步在Lxl工程中添加消息接收函数: void Cclient:OnReceive(int nErrorCode) /TODO:Add your specialized code here andor call the base class ((CLx1Dlg)(AfxGetApp()一m_pMainWnd)-ShowMsg(); Csocket::OnReceive(nErrorCode): void CLx1Dig:ShowMsgO char buf255; m_clientReceive(buf,255); /接收消息到buf里面,长度255字节 CString msg; Msg。Format(s”,buf); AfxMessageBox(msg); /用AfxMessageBox函数显示接收到的字符串 量后的收尾工作不要忘记即在对话框销毁的时候,关闭Socket连接,释放资源.以下以Lxl工程为例,见图。 void CLxlDlg::OnDestroy() Cdialog::OnDestroy0; m_client.Close0; /关闭套接字至此,代码全部添加完毕。
©2010-2024 宁波自信网络信息技术有限公司 版权所有
客服电话:4008-655-100 投诉/维权电话:4009-655-100