基于VC++6.0的Windows网络编程

上传人:桔**** 文档编号:579140574 上传时间:2024-08-25 格式:PPT 页数:24 大小:224KB
返回 下载 相关 举报
基于VC++6.0的Windows网络编程_第1页
第1页 / 共24页
基于VC++6.0的Windows网络编程_第2页
第2页 / 共24页
基于VC++6.0的Windows网络编程_第3页
第3页 / 共24页
基于VC++6.0的Windows网络编程_第4页
第4页 / 共24页
基于VC++6.0的Windows网络编程_第5页
第5页 / 共24页
点击查看更多>>
资源描述

《基于VC++6.0的Windows网络编程》由会员分享,可在线阅读,更多相关《基于VC++6.0的Windows网络编程(24页珍藏版)》请在金锄头文库上搜索。

1、基于基于VC+6.0的的Windows网络编程网络编程主机主机InternetTCP/IP主机主机主要内容1、TCP/IP结构及其特点,在网络编程中用到的重要概念2、Winsock编程原理3、MFC Windows Sockets网络编程的步骤课后:完成一个基于客户机/服务器模式的程序,实现双方通信,至少是一方发数据,一方收。TCP/IP体系结构体系结构 TCP/IP是一个四层协议,它的结构如下图所示: TCP/IP主要包括以下协议:TCP/UDP协议 TCP/UDP协议 TCP (Transmission Control Protocol)和UDP(User Datagram Protoco

2、l)协议属于传输层协议。 其中TCP提供IP环境下的数据可靠传输,它提供的服务包括数据流传送、可靠性、有效流控、全双工操作和多路复用。通过面向连接、端到端和可靠的数据包发送。通俗说,它是事先为所发送的数据开辟出连接好的通道,然后再进行数据发送。 而UDP则不为IP提供可靠性、流控或差错恢复功能。一般来说,TCP对应的是可靠性要求高的应用,而UDP对应的则是可靠性要求低、传输经济的应用。TCP支持的应用协议主要有:Telnet、FTP、SMTP等;UDP支持的应用层协议主要有:NFS(网络文件系统)、SNMP(简单网络管理协议)、DNS(主域名称系统)、TFTP(通用文件传输协议)等。TCP/I

3、P特点 TCP/IP协议的核心部分是传输层协议(TCP、UDP),网络层协议(IP)和物理接口层,这三层通常是在操作系统内核中实现。因此用户一般不涉及。编程时,编程界面有两种形式: 一是由内核心直接提供的系统调用; 二是使用以库函数方式提供的各种函数。前者为核内实现,后者为核外实现。用户服务要通过核外的应用程序才能实现,所以要使用套接字(socket)来实现。 右图是TCP/IP协议核心与应用程序关系图。套接字(Socket) 套接字(Socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,可以将套接字看作不同主机间的进程进行双向通信的端点。一个套接口是通信的一端,在这一端

4、上可以找到与其对应的一个名字。一个正在被使用的套接口都有它的类型和与其相关的进程。套接口存在通信域中,通信域是为了处理一般的线程通过套接口通信而引入的一种抽象概念。套接口通常和同一个域中的套接口交换数据(数据交换也可能穿越域的界限,但这时一定要执行某种解释程序)。WINDOWS 中的套接字只支持一个域网际域。 根据网络通信的性质,套接字可分为两类:流套接字和数据报套接字。 1. 流套接字提供双向的,有序的,无重复并且无记录边界的数据流服务,它适用于处理大量数据,网络传输层可以将数据分散或集中到合适尺寸的数据包中,它是面向连接的。 2. 数据报套接字支持双向的数据流,但它不保证数据传输的可靠性,

5、有序性和无重复性,它是面向无连接的,不保证接受端是否正在侦听,类似于邮政服务。 不论是流套接字还是数据报套接字编程,一般都采用客户机/服务器方式,它们的运作过程基本类似 。客户机/服务器模型 在TCP/IP网络中两个进程间的相互作用的主机模式是客户机/服务器模式(Client/Server model)。该模式的建立基于以下两点:1、非对等作用;2、通信完全是异步的。客户机/服务器模式在操作过程中采取的是主动请示方式: 首先服务器方要先启动,并根据请示提供相应服务:(过程如下) 1、打开一通信通道并告知本地主机,它愿意在某一个公认地址上接收客户请求。 2、等待客户请求到达该端口。 3、接收到重

6、复服务请求,处理该请求并发送应答信号。 4、返回第二步,等待另一客户请求 5、关闭服务器。 客户方: 1、打开一通信通道,并连接到服务器所在主机的特定端口。 2、向服务器发送服务请求报文,等待并接收应答;继续提出请求 3、请求结束后关闭通信通道并终止。Socket编程编程 套接字(Socket)是套接口描述字的简称。Socket提供了一种通信机制,可以用作Windows的一种通信方式。应用程序创建一个套接字后,就能够获得这种机制提供的网络服务功能。对于服务器来讲,它提供了监听网络的连接请求;对于客户机而言,它可以连接到一个给定的主计算机和特定的端口上。客户端和服务器端可以通过套接字对象来发送和

7、接收数据。套接字分别提供了基于连接的协议(TCP)和无连接的协议(UDP),以满足网络连接的可靠性、稳定性和高速性的要求。 为了用套接字实现两台PC间的通信,有下面两种方法: 1.直接利用Windows API函数编写Socket应用程序。 2.利用MFC封装类中的CAsyncSocket类编写Socket网络应用程序。直接利用Windows API函数编写Socket应用程序-Winsock编程原理 1、 Winsock的启动和终止 在所有的Windows Sockets函数中,只有启动函数WSAStartup()和终止函数WSACleanup()是必须使用的。 因为Winsock的服务是以

8、动态链接库Winsock DLL形式实现的,所以必须先调用WSAStartup函数对Winsock DLL进行初始化,协商Winsock的版本支持,并分配必要的资源。WSAStartup函数的原型如下: int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData); 其中,参数wVersionRequested用于指定准备加载的Winsock库的版本;通常的做法是高位字节指定所需要的Winsock库的副版本,而低位字节则是主版本,然后,用宏MAKEWORD(X,Y)(X是高位字节,Y是低位字节)获得wVersionRequested的正

9、确值。LpWSAData参数是指向LPWSADATA结构的指针,该结构包含了加载的库版本有关的信息,这里我们不做详细的介绍。 此外,在应用程序关闭套接字后,还应调用WSACleanup函数终止对Winsock DLL的使用,并释放资源,以备下一次使用。WSACleanup( )函数的原型如下: int WSACleanup (void); 该函数不带任何参数,若调用成功则返回0,否则返回错误。直接利用Windows API函数编写Socket应用程序-Winsock编程原理n2、 Winsock编程模型 不论是流套接字还是数据报套接字编程,一般都采用客户机/服务器方式,它们的运作过程基本类似。

10、流套接字编程模型流套接字编程模型 流套接字(基于TCP协议)的Socket应用程序,需要分别建立服务器和客户端的应用程序,分别创建socket对像。服务进程和客户进程在通信前必须创建各自的套节字并建立连接,然后才能对相应的套接字进行“读”、“写”操作,实现数据的传输。 具体编程步骤如下: 服务器进程创建套接字 服务进程总是先于客户进程启动,服务进程首先调用socket函数创建一个流套接字。 将本地地址绑定到所创建的套接字上以在网络上标识该套接字。这个过程是通过调用bind函数来完成的 。 将套接字置入监听模式并准备接受连接请求。进入监听状态后,通过调用accept函数使套接字作好接受客户连接的

11、准备。 accept函数返回后,返回的addr参数变量中会包含发出连接请求的那个客户机的IP地址信息,而addrlen参数则指出该结构的长度,并返回一个新的套接字描述字,至于原来那个监听套接字,它仍然用于接受其他客户机连接,而且处于监听模式。如果无连接请求,服务进程被阻塞。 客户进程调用socket函数创建客户端套接字。 客户向服务进程发出连接请求。通过调用connect函数可以建立一个端的连接。 当连接请求到来后,被阻塞服务进程的accept函数如中所述生成一个新的套接字与客户套接字建立连接,并向客户返回接受信号。 一旦客户机的套接字收到来自服务器的接受信号,表示客户机与服务器已实现连接,则

12、可以进行传输了。send、recv函数是进行数据的收发的函数。 关闭套接字。一旦任务完成,就必须关掉连接以释放套接字占用的所有资源。通常调用closesocket函数即可达到目的,但closesocket可能会导致数据的丢失,因此,应该在调用closesocket函数之前,应调用shutdown函数从容中断连接,即发送端通知接收端“不再发送数据”或接收端通知发送端“不再接收数据”。基于基于TCPTCP的的SocketSocket应用程序编程时序图如下:应用程序编程时序图如下:服务器socket ( )bind ( )listen ( )accept ( )recv ( )send ( )clo

13、se ( )阻塞,等待客户请求处理服务请求客户机socket ( )connect ( )send ( )recv ( )close ( )建立连接请求数据应答数据数据报套接字编程模型 数据报套接字是无连接的,它的编程过程比流套接字要简单一些。 对于接收端(一般为服务端),先用socket函数建立套接字,再通过bind函数把这个套接字和准备接收数据的IP地址信息绑定在一起,这和前面流套接字一样,但不同的是它不必调用listen和accept,只需等待接收数据。由于它是无连接的,因此它可以接收网络上任何一台机器所发的数据报。常用的接收数据函数是recvfrom。 对于发送端的数据报套接字来说,可

14、以有两种方法发送数据。第一种,也是最简单的一种,便是建立一个套接字,然后调用sendto函数。因为数据报套接字没有连接,在接收端或发送端结束收发数据时,在套接字句柄上调closesocket()函数来释放套接字资源。基于基于UDPUDP的的SocketSocket应用程序编程时序图如下:应用程序编程时序图如下: 因为UDP是无连接的协议,所以只需要在服务器端和客户端分别创建Socket对象,并指定各自的端口,就可以利用sendto和recvfrom等方法来进行数据的发送和接收了。这样就不必调用listen方法去监听端口,也不必利用connect函数去建立连接了。其编程时序图如右:服务器sock

15、et ( )bind ( )readfrom( )sendto ( )close ( )socket ( )bind ( )sendto ( )readfrom( )close ( )客户机阻塞,等待客户数处理服务请求服务请求服务应答 MFC提供了两个Windows Sockets封装类,即CAsyncSocket和CSocket类,它们使编程工作变得相对简单,下面着重介绍一下CAsyncSocket类。 1、 重要的成员函数重要的成员函数 (1)CAsyncSocket和Create CAsyncSocket是构造函数,它构造一个空的套接字对象,其原型为: CAsyncSocket(); 在

16、构造该对象后,必须对其调用Create成员函数,以创建SOCKET句 柄,并将其绑定到指定地址。 在服务端,当监听套接字调用Accept函数时,会自动创建新套接字,用户无需对该套接字调用Create函数,Create函数的原型为: BOOL Create ( UINT nSocketPort = 0, int nSocketTpye = SOCK_STREAM, Long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE , LPCTSTR lpszSocketAddress = NULL ); M

17、FC Windows Sockets网络编程基础网络编程基础 参数说明:nSocketPort:指定套接字使用的端口号,若为0,则由Windows Sockets选择端口。nSocketType:指定套接字的类型。lEvent:注册感兴趣的网络事件。lpszSockAddress:指定套接字的网络地址。如果函数调用成功,则返回非0值,否则返回0值,产生错误。 (2)Accept该函数用于接收连接请求,其原型为:virtual BOOL Accept (CAsyncSocket& rConnectedSocket , SOCKADDR * lpSockAddr = NULL , int * lp

18、SockAddrLen = NULL );参数说明:rConnectedSocket:是CAsyncSocket对象,用于指定可用于连接的新套接字。lpSockAddr:SOCKADDR结构的指针,将返回发送连接请求的套接字地址。lpSockAddrLen:指定lpSockAddr的字节长度。 该函数从连接请求队列中取出第一个成员并创建一个具有相同属性的套接字,然后将其与rConnectSocket连接,而原始的套接字依然保持打开和侦听。如果队列中没有成员,则返回0;否则,操作成功返回非0值。(3)Bind该函数用于将套接字绑定到指定的本地地址,其原型为:BOOL Bind ( UINT nS

19、ocketPort , LPCTSTR lpszSocketAddress = NULL );BOOL Bind ( const SOCKADDR * lpSockAddr , int nSockAddrLen );参数说明:nSocketPort:用于指定套接字应用程序所用的端口。lpszSocketAddress:指定将绑定的网络地址。lpSockAddr:指定将赋予该窗口的地址。nSockAddrLen:指定lpSockAddr的字节长度。(4)Connect该函数用于与一个未连接的数据流或数据报套接字建立连接,其原型为:BOOL Connect ( LPCTSTR lpszHostAd

20、dress , UINT nHostPort );BOOL Connect ( const SOCKADDR * lpSockAddr , int nSockAddrLen );参数说明:lpszHostAddress:用于指定欲连接的服务器网络地址。nHostPort:指定套接字应用程序所使用的端口。lpSockAddr:指定服务器地址信息。nSockAddrLen:指定lpSockAddr参数的字节长度。如果函数调用成功,则返回非0值,否则返回0。(5)Listen该函数用于侦听连接请求,其原型为:BOOL Listen ( int nConnectionBacklog = 5 );参数说

21、明:nConnectionBacklog:用于指定侦听队列的最大套接字数,可取值15。如果函数被调用成功返回非0值,否则返回0。(6)Send该函数用于向对方套接字发送数据,其原型为:virtual int Send ( const void * lpBuf , int nBufLen , int nFlags = 0 );参数说明:lpBuf:指定包含将发送的数据的缓冲区地址。nBufLen:指定lpBuf缓冲区的字节长度。nFlags:指定函数的调用标志,其取值可以是MSG_DONTROUTE和MSG_OOB中的某项或多项的组合。函数调用成功,则返回发送的字符总数。否则返回SOCKET_E

22、RROR。(7)SendTo该函数用于向指定的目标发送数据,其原型为:int SendTo ( const void * lpBuf , int nBufLen , UINT nHostPort , LPCTSTR lpszHostAddress = NULL , int nFlags = 0 );int SendTo ( const void * lpBuf , int nBufLen , const SOCKADDR * lpSockAddr , int nSockAddrLen , int nFlags = 0 );参数说明:lpSockAddr:指定目标套接字的地址。nSockAddr

23、Len:指定lpSockAddr的字节长度。函数调用成功,则返回发送的字符总数,否则返回SOCKET_ERROR。(8)Receive该函数用于从套接字接受数据,其原型为:virtual int Receive ( void * lpBuf , int nBufLen , int nFlags = 0 );参数说明:lpBuf:指定将存放数据的缓冲区。nBufLen:指定lpBuf的字节长度。nFlags:指定函数的调用标志,其取值可以是MSG_PEEK和MSG_OOB中的某项或多项的组合。函数调用成功,则返回发送的字符总数;如果连接被关闭,则返回0。如果函数调用失败,则返回SOCKET_ER

24、ROR。(9)ReceiveFrom该函数用于接收一个数据报,并将源地址存放在SOCKADDR结构或rSocketAddress中,其原型为:int ReceiveFrom ( void * lpBuf , int nBufLen , Cstring& rSocketAddress ,UINT& rSocketPort , int nFlags = 0 );int ReciveFrom ( void * lpBuf , int nBufLen , SOCKADDR * lpSockAddr ,int * lpSockAddrLen , int nFlags = 0 );参数说明:lpBuf:指

25、定将读入数据的缓冲区。nBufLen:指定lpBuf的字节长度。rSocketAddress:CString对象的引用,将返回IP地址。rSocketPort:UINT变量的引用,将返回端口号。lpSockAddr:返回源地址。lpSockAddrLen:指定lpSockAddr的字节长度。nFlags:指定函数调用的标志,其取值与Receive函数中一样。函数调用成功,则返回读入的字符总数;如果连接被关闭,则返回0。如果函数调用失败,则返回SOCKET_ERROR。(10)ShutDown该函数用于使套接字禁止发送和/或接收数据,其原型为:BOOL ShutDown ( int nHow =

26、 sends );参数说明:nHow:指定不允许的操作,它可能的取值有:SD_RECEIVE、SD_SEND或SD_BOTH。如果函数被调用成功返回非0值,否则返回0。(11)Close该函数用于关闭套接字,其原型为:virtual void Close ( );套接字对象的析构函数将自动调用Close函数。2、CAsyncSocket的编程模型的编程模型 在应用程序中使用CAsyncSocket类的一般编程步骤如下: 1.调用类的构造函数创建CAsyncSocket对象。 2.调用Create函数创建SOCKET句柄。 3.如果欲创建的套接字是客户端的,则调用Connect函数向服务器套接字发送连接请求。如果是服务器端套接字,则调用Listen开始侦听客户的连接请求;当收到连接请求后,调用Accept接收该请求。 4.调用CAsyncSocket对象的其他成员函数,完成执行与其他套接字的通信和其他操作(例如,处理阻塞和字节顺序)。 5.销毁CAsyncSocket对象。

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 高等教育 > 研究生课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号