第9章 网络编程_第1页
第9章 网络编程_第2页
第9章 网络编程_第3页
第9章 网络编程_第4页
第9章 网络编程_第5页
已阅读5页,还剩92页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第第9章章 网络编程网络编程9.1 聊天室程序聊天室程序9.1.1聊天室应用程序功能介绍聊天室应用程序功能介绍服务器应用程序服务器应用程序客户端应用程序客户端应用程序9.1.2 程序开发步骤程序开发步骤介绍介绍CStocket程序设计基础程序设计基础使用使用CStocket类开发聊天室客户端应用类开发聊天室客户端应用程序程序使用使用CStocket类开发聊天室服务器端应类开发聊天室服务器端应用程序用程序9.2 CSocket程序设计基础程序设计基础在在VC+中中,利用利用WinSock编程有两种途径编程有两种途径通过通过WinSock API进行编程进行编程利用利用MFC提供的提供的WinSo

2、ck类编程类编程9.2.1 计算机名、计算机名、IP地址和端口地址和端口1. IP地址地址Internet中的每一台主机都分配有一个唯一的中的每一台主机都分配有一个唯一的32位位二进制地址,该地址称为二进制地址,该地址称为IP地址。地址。每个每个IP地址是由网络号和主机号两部分组成的。地址是由网络号和主机号两部分组成的。 IP地址的地址的32位的二进制数,由四个字节组成,并位的二进制数,由四个字节组成,并分成四组,每组一个字节(分成四组,每组一个字节(8位),各组之间用一位),各组之间用一个小圆点号个小圆点号“.”分开。如:某计算机的分开。如:某计算机的IP地址可地址可表示为:表示为:1001

3、010.01100011.01100000.10001100。为了便于记忆,通常把每一组二进制数转换成相为了便于记忆,通常把每一组二进制数转换成相应的十进制数;这台主机的应的十进制数;这台主机的IP地址就是地址就是40。(。(8商都商都dns主机的地主机的地址)址)IP地址的分类地址的分类IP地址通常分为五类,即地址通常分为五类,即A类地址、类地址、B类地址、类地址、C类类地址、地址、D类地址和类地址和E类地址。类地址。 A类地址用于规模较大的网络,主机可以达到类地址用于规模较大的网络,主机可以达到16777214个,个,B类地址适用于中等规模的

4、网络,全类地址适用于中等规模的网络,全世界大约有世界大约有16000个个B类网络,每个类网络,每个B类网络最多可类网络最多可以连接以连接65534台主机。而台主机。而C类地址用于规模较小的类地址用于规模较小的网络,最多只能有网络,最多只能有254个主机个主机 域名系统域名系统DNS域名系统域名系统TCP/IP为人们记忆方便而设计了一种字符为人们记忆方便而设计了一种字符型的计算机命名机制,便形成了网络域名型的计算机命名机制,便形成了网络域名系统(系统(DNS)。)。 域名系统的结构是一种分层次结构。每个域名系统的结构是一种分层次结构。每个域名是由几个域组成的,域与域之间用小域名是由几个域组成的,

5、域与域之间用小圆点圆点“.”分开,最末的域叫顶级域,其它分开,最末的域叫顶级域,其它域的叫子域域的叫子域 。一般格式为:一般格式为:主机名主机名.商标名(企业名)商标名(企业名).单单位性质或地区代码位性质或地区代码.国家代码国家代码 2. 计算机名计算机名winntsystem32driversetchosts文件文件 localhost #localhost为计算机名为计算机名3. 端口端口通讯进程通讯进程 = IP地址地址 + 端口端口有些为特殊目的端口,如有些为特殊目的端口,如80-http; 25-ftp;其它为自由端口其它为自由端口9.2.2 WinSock和和M

6、FC通信的基础是通信的基础是套接口套接口(Socket),一个一个Socket是通信是通信的一端的一端在这一端上用户可以找到与其对应的名字在这一端上用户可以找到与其对应的名字一个正在被使用的套接口都有它的类型和一个正在被使用的套接口都有它的类型和与其相关的进程与其相关的进程流式套接口流式套接口提供了双向的、有序的、无重复并且无记提供了双向的、有序的、无重复并且无记录边界的数据流服务录边界的数据流服务数据报套接口数据报套接口支持双向的数据流支持双向的数据流,但并不保证是可靠、有但并不保证是可靠、有序和无重复的序和无重复的一个数据报套接口接收信息的进程有可能一个数据报套接口接收信息的进程有可能发现

7、信息重复了发现信息重复了,或者和发出时的顺序不同或者和发出时的顺序不同它保留了记录边界它保留了记录边界可以用来向许多系统支持的网络发送广播可以用来向许多系统支持的网络发送广播数据包数据包MFC中提供了两个类用于中提供了两个类用于WinSock编程:编程:CAsyncSocket类和类和CSocket类类CAsyncSocket类类对对Windows Sockets API进行了封装进行了封装提供基于异步通信的套接口封装功能提供基于异步通信的套接口封装功能适用于需要充分利用适用于需要充分利用Winsock API的灵活性的灵活性,并使用回调函数来响应网络事件的情况并使用回调函数来响应网络事件的情

8、况CSocket类类是是CAsyncSocket类的派生类类的派生类,该类对该类对WinSock类进行了更多的封装类进行了更多的封装,提供更多提供更多高层次的功能高层次的功能利用利用CArchive类进行数据传输类进行数据传输,从而使利从而使利用该类进行数据传输的过程与用该类进行数据传输的过程与MFC的串的串行化一致行化一致该类通过对该类通过对Windows消息的处理来实现消息的处理来实现阻塞阻塞,从而实现基于从而实现基于CAchive的同步数据的同步数据传输传输注意注意:在编写网络程序时在编写网络程序时,所创建的新类必须声明所创建的新类必须声明自己是自己是CAsyncSocket或或CSoc

9、ket类的子类类的子类原因是想捕获激活的事件原因是想捕获激活的事件有一系列函数可以调用有一系列函数可以调用,以响应每一个事件以响应每一个事件,这些函数使用同样的定义这些函数使用同样的定义,只是函数名有些只是函数名有些差别差别 函数函数事件描述事件描述OnAccept监听方调用此函数表示对方程序的连接请求正等监听方调用此函数表示对方程序的连接请求正等待被接受待被接受OnClose表示连接的另一端的应用程序已经关闭它的表示连接的另一端的应用程序已经关闭它的Socket,或者连接已经丢失或者连接已经丢失,接着接着,收到此通知的收到此通知的Socket应该应该关闭关闭OnConnect表示与对方程序的

10、连接已经完成表示与对方程序的连接已经完成,程序现在可以通程序现在可以通过过Socket发送或接收消息发送或接收消息OnOutofBanData表示收到外带数据表示收到外带数据,外带数据在一个逻辑上独立的外带数据在一个逻辑上独立的通道上发送通道上发送,用于经济数据的发送用于经济数据的发送,不是常规数据的不是常规数据的一部分一部分,Send和和Receive方法都用第方法都用第3个参数个参数,用于外用于外带数据的发送和接收带数据的发送和接收OnReceive表示通过表示通过Socket连接的数据已经收到连接的数据已经收到,可调用可调用Receive函数接收函数接收OnSend表示通过表示通过Soc

11、ket已经准备好发送数据已经准备好发送数据,连接完成即连接完成即可调用此函数可调用此函数.通常通常,程序传送给程序传送给Send函数的数据太函数的数据太多多,超过了单个数据包中可以发送的数量超过了单个数据包中可以发送的数量,这时也可这时也可以调用此函数以调用此函数.这表示这表示,已发送所有数据已发送所有数据,程序可以发程序可以发送下一个缓冲数据送下一个缓冲数据9.2.3 WinSock的工作原理的工作原理WinSock的工作方式为服务器的工作方式为服务器-客户模式客户模式有面向连接和无连接两种通信方式有面向连接和无连接两种通信方式有连接的通信有连接的通信使用的是使用的是TCP协议协议,通过通过

12、TCP协议可以与指协议可以与指定定IP地址的主机建立连接地址的主机建立连接,同时利用建立的同时利用建立的连接可以双向交换数据连接可以双向交换数据采用流的方式进行数据传输采用流的方式进行数据传输,要求客户必须要求客户必须指定服务器的地址指定服务器的地址能保证通过网络进行数据传输的可靠性能保证通过网络进行数据传输的可靠性WinSock进行有连接的通信模型进行有连接的通信模型创建套接口创建套接口:Create()绑定套接口绑定套接口:Bind()侦听接口侦听接口:Listen()等待客户请求等待客户请求:Accept()数据读数据读/写写:Receive/Send关闭套接口关闭套接口:Close()

13、服务器端服务器端创建套接口创建套接口:Create()连接到服务器连接到服务器:Connect()数据读数据读/写写:Receive/Send关闭套接口关闭套接口:Close()客户端客户端建立连接建立连接阻塞,等待客户数据阻塞,等待客户数据请求请求/应答数据应答数据在有客户连接请求之前在有客户连接请求之前,服务器线程或进程服务器线程或进程将会阻塞将会阻塞,直到有客户程序成功地连接到了直到有客户程序成功地连接到了服务器上后才继续往下运行服务器上后才继续往下运行在单线程的应用程序中在单线程的应用程序中,服务器线程或进程服务器线程或进程阻塞就意味着整个应用程序都无法继续运阻塞就意味着整个应用程序都

14、无法继续运行行,可以选择多线程的方式来解决可以选择多线程的方式来解决解决阻塞问题的方案解决阻塞问题的方案利用产生和响应网络事件的方式来解决阻利用产生和响应网络事件的方式来解决阻塞问题塞问题服务器在等待客户请求时并不进入阻塞状服务器在等待客户请求时并不进入阻塞状态态,而是直接返回而是直接返回,进入侦听网络事件的循环进入侦听网络事件的循环中中当需要读客户数据时当需要读客户数据时,同样也并不陷入阻塞同样也并不陷入阻塞状态状态,而是直接返回到消息循环中而是直接返回到消息循环中利用利用WinSock进行无连接的通信进行无连接的通信使用的是使用的是UDP协议协议,通过通过UDP协议可以往指协议可以往指定定

15、IP地址的主机发送数据地址的主机发送数据,同时也可以从指同时也可以从指定定IP地址的主机接收数据地址的主机接收数据发送和接收方处于相同的地位发送和接收方处于相同的地位,没有主次之没有主次之分分发送数据发送数据int CAsyncSocket:SendTo( cont void * lpBuf, int nBufLen, UINT nHostPort, LPCTSTR lpszHostAddress = NULL, int nFlag = 0);接收数据接收数据int CAsyncSocket:ReceiveFrom( void * lpBuf, int nBufLen, CString &am

16、p; rSocketAddress UINT& rSocketPort, int nFlags = 0);2. 无连接通讯模型无连接通讯模型创建套接口创建套接口:Create()绑定套接口绑定套接口:Bind()接收数据接收数据:ReceiveFrom()发送数据发送数据:SendTo()关闭套接口关闭套接口:Close()服务器端服务器端创建套接口创建套接口:Create()发送数据发送数据:SendTo()接收数据接收数据:ReceiveFrom()关闭套接口关闭套接口:Close()客户端客户端服务请求服务请求阻塞,等待客户数据阻塞,等待客户数据服务应答服务应答绑定套接口绑定套接

17、口:Bind()利用利用UDP协议发送和接收都可以是双向的协议发送和接收都可以是双向的,就是说就是说,任何一个主机都可以发送和接收数任何一个主机都可以发送和接收数据据UDP协议是无连接的协议是无连接的,所以发送的数据不一所以发送的数据不一定能被接收定能被接收,接收的顺序也有可能与发送的接收的顺序也有可能与发送的顺序不一致顺序不一致发送方在端口发送方在端口800上向接收方端口上向接收方端口900发送数据的部分子函数发送数据的部分子函数/ m_port:800,m_ip=_T(“”)void CMyClientDlg:OnLink()/ TODO:Add extra initia

18、lization hereUpdateData(true);m_socketRecv.Creat(m_port,SOCK_DGRAM,m_ip);m_socketRecv.Bind(m_port,m_ip);SetTimer(2,3000,NULL);.void CMyClientDlg:OnTimer(UINT nIDEvent)char szRecv20;int iRecv = m_socketRecv.ReceiveFrom(szRecv,10,m_ip,m_port,0);szRecviRecv=0;m_edit1= szRecv;UpdateData(false);CDialog:O

19、nTimer(nIDEvent);void CMyserverDlg:OnLink()UpdateData(true);m_socketSend.Creat(m_port,SOCK_DGRAM,NULL);m_socketSend.Bind(m_port,m_ip);SetTimer(1,3000,NULL);.void CMyserverDlg:OnTimer(UINT nIDEvent)Static iIndex=0;char szSend20=“1234567890”;sprintf(szSend, “%d”,iIndex+);m_transmit_info = sz;Send;Upda

20、tedata(false);int iSend = m_socketSend.SendTo(szSend,10,m_port,m_ip,0);CDialog:OnTimer(nIDEvent);9.3 基于基于CSocket的网络编程的网络编程面向有连接的流式套接口提供了可靠的、面向有连接的流式套接口提供了可靠的、有序的且不重复的连接有序的且不重复的连接在进行连接时在进行连接时,服务器端通常在一个众所周服务器端通常在一个众所周知的端口侦听知的端口侦听,当客户端发出连接请求时当客户端发出连接请求时,服服务器被唤醒务器被唤醒,然后为客户应用程序提供服务然后为客户应用程序提供服务或进行数据传输或进行

21、数据传输服务器端服务器端从从CSocket类派生一个新类类派生一个新类创建一个创建一个CSocket派生类对象派生类对象调用调用CSocket:Creat()函数创建一个套接口函数创建一个套接口,并指定并指定一个端口一个端口调用调用CSocket:Listen()函数侦听端口函数侦听端口在在CSocket派生类中添加虚函数派生类中添加虚函数OnAccept(),用于用于响应客户应用程序的连接请求响应客户应用程序的连接请求,通过调用通过调用CSocket:Accept()函数接受客户的连接请求函数接受客户的连接请求,在在Receive()函数中进行读操作函数中进行读操作通信结束时通信结束时,调用

22、读写套接口的调用读写套接口的Close()函数关闭各函数关闭各个客户分配的读写套接口个客户分配的读写套接口客户端客户端创建一个创建一个CSocket类的派生类对象类的派生类对象,用于连接用于连接和读写和读写调用调用CSocket:Creat()函数创建一个套接口函数创建一个套接口调用调用CSocket:Connect()函数连接服务器的函数连接服务器的指定端口指定端口调用调用CSocket:Send()函数发送数据函数发送数据在在CSocket:OnReceive()函数中进行读操作函数中进行读操作在结束通信时在结束通信时,调用调用CSocket:Close()函数关函数关闭套接口闭套接口9.

23、4 聊天室客户端应用程序聊天室客户端应用程序9.4.1 创建工程创建工程MyWc9.4.3 创建一个新类创建一个新类CWCSock9.4.4 修改修改CWCSocket类类(1) 在在WCSock.h中定义存储数据的结构体中定义存储数据的结构体typedef structchar m_strName255; /客户名字客户名字char m_dbData255; /要发送的数据或信息要发送的数据或信息BOOL m_bOnline; /客户是否在线客户是否在线_DATA;(2) 在在CWCSock类中添加数据成员类中添加数据成员/ WCSock.hclass CWCSock : public CS

24、ocket./ Overridespublic:_DATA m_Dat; .(3) 在在WCSock.h中定义自定义消息,以使中定义自定义消息,以使CWCSock能够同应用程序主窗口通信能够同应用程序主窗口通信#define RE_RECEIVED WM_USER+1(4) 编写编写OnReceive()函数代码函数代码void CWCSock:OnReceive(int nErrorCode)/TODO:Add your specialized code here and/or call the base classif (Receive (&m_Dat,sizeof(m_Dat)=

25、 = sizeof(m_Dat):PostMessage(:AfxGetApp()-m_pMainWnd-m_hWnd, RE_RECEIVED, (WPARAM)&m_Dat,0);CSocket:OnReceive(nErrorCode);(1) 为为CMyWcDlg类添加相应成员变量类添加相应成员变量9.4.5 为编辑控件引入变量为编辑控件引入变量/ MyWcDlg.hclass CMyWcDlg : public CDialog/ Constructionpublic:CMyWcDlg(CWnd* pParent = NULL);/ standard constructor_D

26、ATA m_Dat;.(1)为为CMyWcDlg类添加相应的成员变量类添加相应的成员变量LRESULT OnReceive(WPARAM wparam,LPARAM lParam);/Dialog Data/AFX_DATA(CMyWcDlg)Enum IDD = IDD_MYWC_DIALOG;CListBox m_ctlSent;CListBox m_ctlRecvd;int m_nPort;CString m_server_name;CString m_client_name;CString m_send_info(2) 在构造函数中进行初始化在构造函数中进行初始化/ MyWcDlg.c

27、ppCMyWcDlg:CMyWcDlg(CWnd* pParent /*=NULL*/): CDialog(CMyWcDlg:IDD, pParent)memset(&m_Dat,0,sizeof(m_Dat);/AFX_DATA_INIT(CMyWcDlg)m_client_name = _T(localhost);m_send_info = _T();m_server_name = _T(localhost);m_nPort = 800;/AFX_DATA_INIT/ Note that LoadIcon does not require a subsequent DestroyI

28、con in Win32m_hIcon = AfxGetApp()-LoadIcon(IDR_MAINFRAME);(3) 添加数据交换代码添加数据交换代码/ MyWcDlg.cppvoid CMyWcDlg:DoDataExchange(CDataExchange* pDX)CDialog:DoDataExchange(pDX);/AFX_DATA_MAP(CMyWcDlg)DDX_Control(pDX, IDC_SENT_INFO, m_ctlSent);DDX_Control(pDX, IDC_RECEIVED_INFO, m_ctlRecvd);DDX_Text(pDX, IDC_C

29、LIENT_NAME, m_client_name);DDX_Text(pDX, IDC_SEND_INFO, m_send_info);DDX_Text(pDX, IDC_SERVER_NAME, m_server_name);DDX_Text(pDX, IDC_SERVER_PORT, m_nPort);/AFX_DATA_MAP9.4.6 建立建立CMyWcDlg类与类与CWCSock类的关联类的关联在在CMyWcDlg类定义前添加如下语句:类定义前添加如下语句:/ MyWcDlg.h#include WCSock.h在在CMyWcDlg类定义中添加如下语句:类定义中添加如下语句:/ M

30、yWcDlg.hclass CMyWcDlg : public CDialog/ Constructionpublic:CWCSock sockClient;9.4.7 编写程序代码编写程序代码1. 添加消息响应函数添加消息响应函数2. 编写程序代码编写程序代码void CMyWcDlg:OnConnect() /更新关联变量,如服务器名、端口号更新关联变量,如服务器名、端口号UpdateData(true);/创建套接口创建套接口if(!sockClient.Create()AfxMessageBox(Create WC Socket failed);PostQuitMessage(0);/

31、与服务器连接与服务器连接if(!sockClient.Connect(m_server_name,m_nPort)MessageBox(连接失败连接失败!);return;m_Dat.m_bOnline=true;void CMyWcDlg:OnSend() /更新关联变量,如要发送的消息更新关联变量,如要发送的消息UpdateData(true);m_Dat.m_bOnline=true;memset(m_Dat.m_dbData,0,255);memcpy(m_Dat.m_dbData,m_send_info,m_send_info.GetLength();strcpy(m_Dat.m_s

32、trName,m_client_name);/发送的消息发送的消息int iSent=sockClient.Send(&m_Dat,sizeof(m_Dat);/如发送成功,将其发送的消息添加并显示在列表框如发送成功,将其发送的消息添加并显示在列表框if(iSent!=SOCKET_ERROR)m_ctlSent.AddString(m_send_info);UpdateData(false); /显示显示void CMyWcDlg:OnClose() m_Dat.m_bOnline=false;strcpy(m_Dat.m_dbData,886);sockClient.Send(&a

33、mp;m_Dat,sizeof(m_Dat);/断开与服务器的连接断开与服务器的连接sockClient.Close();9.4.8 处理自定义消息处理自定义消息添加消息映射宏:添加消息映射宏:/ MyWcDlg.cppBEGIN_MESSAGE_MAP(CMyWcDlg, CDialog)/AFX_MSG_MAP(CMyWcDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_SEND, OnSend)ON_BN_CLICKED(IDC_CONNECT, OnConnect)ON_BN_CLICKE

34、D(IDC_CLOSE, OnClose)ON_MESSAGE(RE_RECEIVED,OnmyReceive)/AFX_MSG_MAPEND_MESSAGE_MAP()声明函数声明函数OnmyReceive():/ MyWcDlg.h class CMyWcDlg : public CDialog.LRESULT OnmyReceive(WPARAM wparam, LPARAM lParam);.添加函数添加函数OnmyReceive()的函数体:的函数体:LRESULT CMyWcDlg:OnmyReceive(WPARAM wparam,LPARAM lParam)_DATA *dat

35、;dat=new _DATA;memcpy(dat,(_DATA*)wparam,sizeof(_DATA);CString str=dat-m_strName;str+=:;str+=dat-m_dbData;m_ctlRecvd.AddString(str);UpdateData(false);delete dat;return 1;9.4.9 处理控件的更新处理控件的更新OnClose()和和OnInitDialog()最后加上最后加上GetDlgItem(IDC_CONNECT)-EnableWindow(true);GetDlgItem(IDC_SEND)-EnableWindow(

36、false);GetDlgItem(IDC_CLOSE)-EnableWindow(false);GetDlgItem(IDC_SERVER_PORT)-EnableWindow(true);GetDlgItem(IDC_CLIENT_NAME)-EnableWindow(true);GetDlgItem(IDC_SERVER_NAME)-EnableWindow(true);OnConnect()最后加上最后加上GetDlgItem(IDC_CONNECT)-EnableWindow(false);GetDlgItem(IDC_SEND)-EnableWindow(true);GetDlgI

37、tem(IDC_CLOSE)-EnableWindow(true);GetDlgItem(IDC_SERVER_PORT)-EnableWindow(false);GetDlgItem(IDC_CLIENT_NAME)-EnableWindow(false);GetDlgItem(IDC_SERVER_NAME)-EnableWindow(false);9.4.10 编译、连接运行编译、连接运行9.4.11 ClistBox类类函数名函数名说明说明ModifyStyle改变列表框的风格改变列表框的风格AddString向列表框加入项向列表框加入项InsertString在指定位置加入一个字符串

38、项在指定位置加入一个字符串项SetTopIndex设置某点位于列表框的顶部设置某点位于列表框的顶部DeleteItem删除某项删除某项GetCount获得总项数获得总项数GetCurSel获得所选项序号获得所选项序号GetText获得指定项文本获得指定项文本9.5 聊天室服务器端应用程序聊天室服务器端应用程序9.5.1 创建工程创建工程MyWs9.5.3 创建一个侦听类创建一个侦听类CLSock9.5.4 增加一个读增加一个读/写类写类CRWSock9.5.5 为编辑框控件引入变量为编辑框控件引入变量9.5.6 修改修改CRWSock和和CLSock类类1. 添加结构体成员变量添加结构体成员变

39、量typedef structchar m_strName255; /客户名字客户名字char m_dbData255; /要发送的数据或信息要发送的数据或信息BOOL m_bOnline; /客户是否在线客户是否在线_DATA;在在CRWSock类中添加数据成员类中添加数据成员/ LSock.hclass CRWSock : public CSocket/ Attributespublic:_DATA m_Dat;.2. 添加添加CMyWsDlg类指针成员变量,修改类指针成员变量,修改CMyWsDlg的构造函数的构造函数/ LSock.hclass CMyWsDlg; /放到文件最前面放到文

40、件最前面.class CRWSock : public CSocket/ Attributespublic:_DATA m_Dat;/ Operationspublic:CRWSock(CMyWsDlg *p);virtual CRWSock();.private:CMyWsDlg *m_p;/ LSock.cppCRWSock:CRWSock(CMyWsDlg *p)m_p=p;3. 在在CLSock类,添加类,添加CMyWsDlg类指针成类指针成员变量,修改员变量,修改CLSock的构造函数的构造函数/ LSock.hclass CLSock : public CSocket/ Attri

41、butespublic:/ Operationspublic:CLSock(CMyWsDlg *p);virtual CLSock();.protected:private:CMyWsDlg *m_p;/ LSock.cpp CLSock:CLSock(CMyWsDlg *p)m_p=p;9.5.7 修改修改CMyWsDlg类类1. 添加头文件添加头文件/ MyWsDlg.h #include LSock.h2. 添加成员变量和成员函数添加成员变量和成员函数/ MyWsDlg.hclass CMyWsDlg : public CDialogpublic:CMyWsDlg(CWnd* pPare

42、nt = NULL);/ standard constructorvoid AcceptClient();void ReadMessage(CRWSock *sock);_DATA m_Dat;.DECLARE_MESSAGE_MAP()private:void SendSocketMessage(CRWSock *socket,_DATA *buffer);/添加一个添加一个CPtrList类的对象,用于管理各个客户的套接口类的对象,用于管理各个客户的套接口CPtrList m_list;CRWSock *m_clientSocket;CLSock *m_listenSocket;3. 初始

43、化成员变量初始化成员变量/ MyWsDlg.cppCMyWsDlg:CMyWsDlg(CWnd* pParent /*=NULL*/): CDialog(CMyWsDlg:IDD, pParent)m_clientSocket=NULL;m_listenSocket=NULL;/AFX_DATA_INIT(CMyWsDlg)m_server_port = 800;/AFX_DATA_INIT/ Note that LoadIcon does not require a subsequent DestroyIcon in Win32m_hIcon = AfxGetApp()-LoadIcon(I

44、DR_MAINFRAME);4. 在在MyWsDlg.cpp文件中添加实现函数体文件中添加实现函数体/ MyWsDlg.cppvoid CMyWsDlg:AcceptClient()m_clientSocket=new CRWSock(this);if(!m_listenSocket-Accept(*m_clientSocket)AfxMessageBox(请求连接失败请求连接失败);delete m_clientSocket;m_clientSocket=NULL;return;m_list.AddTail(m_clientSocket);9.5.8 处理接收客户的信息处理接收客户的信息1.

45、 添加虚拟函数添加虚拟函数OnReceive()此处应该为此处应该为CRWSock,但程序编但程序编写时显示不出来写时显示不出来CRWSock,所所以在以在LSock.h和和LSock.cpp中对中对应位置进行了手动修改应位置进行了手动修改2. 编写程序代码编写程序代码/ LSock.cppvoid CLSock:OnReceive(int nErrorCode) m_p-ReadMessage(this);CSocket:OnReceive(nErrorCode);void CMyWsDlg:ReadMessage(CRWSock *sock)int len=sock-Receive(&am

46、p;m_Dat,sizeof(m_Dat);if(len=sizeof(m_Dat)_DATA *dat=&m_Dat;CString str=收到客户机收到客户机(;str+=dat-m_strName;str+=)的消息的消息:;str+=dat-m_dbData;m_ctlRecvd.AddString(str);if(m_Dat.m_bOnline)SendSocketMessage(sock,&m_Dat);else /如果客户不在线,则关闭套接口,并从链表中删除如果客户不在线,则关闭套接口,并从链表中删除sock-Close();POSITION pos;pos=m

47、_list.Find(sock);m_list.RemoveAt(pos);if(sock!=NULL) delete sock;void CMyWsDlg:SendSocketMessage(CRWSock *socket,_DATA *buffer)POSITION pos=m_list.GetHeadPosition();while(pos!=NULL)CRWSock *client=(CRWSock*)m_list.GetNext(pos);if(client=socket) continue; /不发给自身不发给自身client-Send(&m_Dat,sizeof(m_Da

48、t);9.5.9 处理客户的连接请求处理客户的连接请求1. 在在CMyWsDlg类中,添加一个类中,添加一个CPtrList类的对象,用于管理各个客户的套接口类的对象,用于管理各个客户的套接口/ MyWsDlg.hclass CMyWsDlg : public CDialogpublic:CMyWsDlg(CWnd* pParent = NULL);/ standard constructorvoid AcceptClient();void ReadMessage(CRWSock *sock);_DATA m_Dat;/CPtrList m_list;.2. 在在CLSock类中添加虚拟函数类

49、中添加虚拟函数OnAccept(),用于处理客户的连接请求用于处理客户的连接请求void CLSock:OnAccept(int nErrorCode) ASSERT(m_p);m_p-AcceptClient();CSocket:OnAccept(nErrorCode);/ MyWsDlg.cppvoid CMyWsDlg:AcceptClient()m_clientSocket=new CRWSock(this);if(!m_listenSocket-Accept(*m_clientSocket)AfxMessageBox(请求连接失败请求连接失败);delete m_clientSocket;m_clientSocket=NULL;return;m_list.AddTail(m_clientSocket);9.5.10 为启动,关闭按钮的为启动

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论