网络聊天编程.ppt
《网络聊天编程.ppt》由会员分享,可在线阅读,更多相关《网络聊天编程.ppt(36页珍藏版)》请在三一办公上搜索。
1、第8章 网络聊天编程,第一部分 应用实践,8.1 为应用系统加入Socket支持,8.2 编写聊天模块前的准备,8.3 编写聊天模块代码,第二部分 知识点链接,L8.1 为应用系统加入Socket支持,L8.2 编写聊天模块代码,第8章 网络聊天编程,系统功能:单击菜单中的“交谈”“对话”,弹出“对话(Socket聊天)”对话框,单击“谁在线上”可以搜索工作组中所有用户的计算机名,双击一个计算机名,该计算机名即显示在左边文本框中,单击空白文本区,单击“我要上线”可上线等待来自其他用户发送的数据并在文本框中显示,否则不能接收消息,但能够给已上线的用户发送消息。,图8.1 双方聊天,第一部分 应用
2、实践,8.1 为应用系统加入Socket支持为MFC程序加入Socket支持一般有两种方法,第一种是在用MFC AppWizard(exe)创建一个单文档应用程序时,在向导的第4步选中Windows Sockets,如图8.2所示。,图8.2 Windows Sockets支持,8.1 为应用系统加入Socket支持,为MFC程序加入Socket支持一般有两种方法,第一种是在用MFC AppWizard(exe)创建一个单文档应用程序时,在向导的第4步选中Windows Sockets,如图8.2所示。(1)打开工程,切换到FileView,双击打开头文件StdAfx.h,在其中加入一行:#i
3、nclude/MFC socket extensions(2)mpr.lib这个库里面封装了Windows Networking(Wnet)函数,这是一组网络控制函数,比如可以利用这些函数来列举局域网内所有机器名称,IP地址以及其他相关信息。为了使用这些函数需要在StdAfx.h中加入一行:#pragma comment(lib,mpr)(3)切换到ClassView,打开CXSCJApp下的InitInstance函数,在函数体最前面添加如下代码以初始化Sockets:BOOL CXSCJApp:InitInstance()if(!AfxSocketInit()/是否初始化成功AfxMess
4、ageBox(Windows通信端口初始化失败);return FALSE;,8.2 编写聊天模块前的准备,(1)设置界面如图8.3所示,新建对话框,设置标题为Sockets聊天,ID为IDD_P2PCHAT,并在菜单上添加相应的项如“对话”,并编写弹出本对话框的命令代码。,图8.3“设置Socket聊天”对话框,8.2 编写聊天模块前的准备,添加“对话”菜单项ID_P2PCHAT的COMMAND消息到CXSCJView类中,代码如下:void CXSCJView:OnP2pchat()/TODO:Add your command handler code hereCDlgP2P myDlgP
5、2P;myDlgP2P.DoModal();在XSCJView.cpp中添加头文件:#include DlgP2P.h(2)设置接收文本框IDC_SHOWSTR控件的属性设置如图8.4(左)所示,设置发送文本框IDC_SENDSTR的属性如图8.4(右)所示。,图8.4 设置编辑框的Styles属性,8.2 编写聊天模块前的准备,(3)打开列表控件的属性对话框,将“查看”选为“小图标”,利于网络聊天时各在线用户名的完全显示。单击编排(Layout)测试(Test)后显示界面如图8.5所示。,图8.5 聊天模块界面,8.3 编写聊天模块代码,(1)为对话框新建类CDlgP2P,为控件添加关联变量
6、如图8.6所示。,图8.6 设置控件关联变量,8.3 编写聊天模块代码,(2)在对话框类CDlgP2P 的头文件DlgP2P.h中加入变量和函数声明。class CDlgP2P:public CDialog/Construction public:CDlgP2P(CWnd*pParent=NULL);/standard constructor CString GetIP(CString username);/得到目标机器IP void GetName(char Temp64);/取得本机名 bool connectFlag;/网络连接标识 void ShowRecvData();/显示接收的数
7、据 void GetLanActiveComputer();/获取本地活动计算机机器名称;,8.3 编写聊天模块代码,(3)在DlgP2P.cpp文件中加入全局变量如下:static int CreatedFlag=0;/是否已建立服务器SOCKET m_socket,m_hSocket;/建立套接字描述符sockaddr_in m_addr;/sockaddr_in结构为套接字储存套接字地址信息sockaddr_in m_raddr;sockaddr_in m_caddr;char*message=NULL;/聊天内容接收框中的消息变量char*name=NULL;/聊天内容接收框中的主机名
8、变量int nItem;/CList控件中显示内容(主机名)的序号CString changstr;/中间变量CString strname;/同上UINT AcceptThread(LPVOID lpvoid);/接收线程SOCKET m_cSocket;/客户端Socket,8.3 编写聊天模块代码,(4)取得本机名。void CDlgP2P:GetName(char Temp64)/取本机(Local Machine)的主机名(即Windows中的本机计算机名)gethostname(Temp,64);(5)添加WM_INITDIALOG消息,用本机用户名初始化全局变量changstr。
9、BOOL CDlgP2P:OnInitDialog()CDialog:OnInitDialog();/TODO:Add extra initialization herechar localname64;GetName(localname);changstr=localname;return TRUE;/return TRUE unless you set the focus to a control/EXCEPTION:OCX Property Pages should return FALSE,8.3 编写聊天模块代码,(6)在DlgP2P.cpp中添加GetLanActiveComput
10、er函数,用枚举的方法找到局域网里所有打开的机器。该函数的实现代码中用到了几个枚举网络资源的函数,其中包括:WnetOpenEnum函数、WnetEnumResource函数和WnetCloseEnum函数。(7)根据计算机名得到IP地址。CString CDlgP2P:GetIP(CString username)CString hostaddr;struct hostent*hostname=gethostbyname(username);for(int i=0;hostname!=NULL,8.3 编写聊天模块代码,(8)创建ShowRecvData(),该函数负责将接收到的数据显示在文
11、本接收框中。void CDlgP2P:ShowRecvData()CString tempstr;tempstr=;if(name!=NULL(9)编写线程AcceptThread,作用是接收来自多个客户端的连接并发送数据。该线程参数为OnCreathost()传来的对话框指针,根据该指针可以对聊天对话框中显示接收数据的IDC_SHOWSTR文本框进行操作。,8.3 编写聊天模块代码,(10)为“我要上线”按钮添加OnCreathost()事件。编写代码时,需要用到许多Sockets编程常用函数,包括:sockets()、bind()、listen()、connect()、accept()、s
12、end()、recv()和closesockets。主要功能是打开Socket,绑定IP和端口号,开始监听,启动线程AcceptThread接受数据。,8.3 编写聊天模块代码,(11)为ListCtrl控件IDC_USER添加双击事件NM_DBLCLK。void CDlgP2P:OnDblclkUser(NMHDR*pNMHDR,LRESULT*pResult)/TODO:Add your control notification handler code herePOSITION pos;m_showname.SetWindowText();nItem=0;pos=m_List.GetFi
13、rstSelectedItemPosition();/取第一个选择项的positonif(pos=NULL)return;elsewhile(pos)/如果用户选择了多项,则取最后选择的一项nItem=m_List.GetNextSelectedItem(pos);m_name=m_List.GetItemText(nItem,0);UpdateData(FALSE);/传到“发送计算机”编辑框中,方向是变量到控件*pResult=0;,8.3 编写聊天模块代码,(12)为“谁在线上”按钮添加BN_CLICKED事件,该事件负责将双击事件传来的用户名加入文本框IDC_SENDNAME中。voi
14、d CDlgP2P:OnFinduser()/TODO:Add your control notification handler code hereCString strTemp;strTemp=请稍候.;m_FindBtn.SetWindowText(strTemp);m_List.DeleteAllItems();/先清空原来显示的计算机名列表GetLanActiveComputer();/再次取得局域网中的计算机名Sleep(1000);/程序冻结1000ms,获取计算机名时避免其他操作strTemp=谁在线上?((13)为按钮IDC_SENDBUTTON添加OnSend事件,作用是根
15、据文本框IDC_SENDNAME传入的用户名,选择服务端,创建发送套接字,向指定计算机发送消息。,第二部分 知识点链接,L8.1 为应用系统加入Socket支持L1.SocketSocket的数据传输是一种特殊的I/O,Socket也是一种文件描述符。Socket具有一个类似于文件打开的函数调用Socket,该函数返回一个整型的Socket描述符,随后建立连接,数据传输等操作都是通过该Socket实现的。Socket分为三类:流式Socket(SOCK_STREAM),数据报Socket(SOCK_DGRAM)及原始Socket(SOCK_RAW)。流式Socket为面向连接,数据报Socke
16、t为面向无连接;原始Socket主要用于一些协议的开发和测试新的网络协议的实现,可以进行比较底层的操作,如IP的直接访问。Windows Sockets是微软公司的网络程序设计接口,它是从BSD UNIX Socket扩展而来的。它不仅包含了BSD UNIX Socket风格的库函数,也包含了一组对Windows的扩展库函数,使程序员能够充分利用Windows的消息驱动机制进行编程。,L8.1 为应用系统加入Socket支持,L8.2 编写聊天模块代码L1.sockaddr_instruct sockaddr结构为套接字储存套接字地址信息。语法:struct sockaddr unsigned
17、 short sa_family;/*地址家族,AF_xxx*/char sa_data14;/*14字节协议地址*/;参数说明:sa_family TCP/IP协议族默认是AF_INET sa_data包含套接字中的目标地址和端口信息 为了处理struct sockaddr,使用另一个类似的结构:struct sockaddr_in(in代Internet)。struct sockaddr_in short int sin_family;/*通信类型*/unsigned short int sin_port;/*端口*/struct in_addr sin_addr;/*Internet 地
18、址*/unsigned char sin_zero8;/*与sockaddr结构的长度相同*/;,L8.2 编写聊天模块代码,L2.gethostname函数gethostname函数用以返回本地主机的标准主机名。#include/使用前包含头文件语法:int PASCAL FAR gethostname(char FAR*name,int namelen);参数说明:name 一个指向将要存放主机名的缓冲区指针namelen缓冲区的长度该函数把本地主机名存放入由name参数指定的缓冲区中。返回的主机名是一个以NULL结束的字符串。主机名的形式取决于Windows Sockets,它可能是一个
19、简单的主机名,或者是一个域名。然而,返回的名字必定可以在gethostbyname()和 WSAAsyncGetHostByName()中使用。如果没有错误发生,gethostname()返回0,否则它返回SOCKET_ERROR。应用程序可以通过WSAGetLastError()来得到一个特定的错误代码。错误代码:WSAEFAULT 名字长度参数太小WSANOTINTIALISED 在应用这个API前,必须成功地调用WSAStartup()WSAENTDOWN Windows Sockets实现检测到了网络子系统的错误WSAEINPROGRESS 一个阻塞的Windows Sockets操作
20、正在进行,L8.2 编写聊天模块代码,L3.枚举网络资源的函数1WnetOpenEnum函数WnetOpenEnum函数用于启动对网络资源进行枚举的过程。语法:DWORD WnetOpenEnum(DWORD dwScope,DWORD dwType,DWORD dwUsage,LPNETRESOURCE lpNetResource,LPHANDLE lphEnum);参数说明:DwScope表示网络枚举的范围DwType表示枚举的资源类型DwUsage表示枚举资源的用法LpNetResource用于返回网络资源信息LphEnum表示枚举的资源句柄指针,L8.2 编写聊天模块代码,2WnetE
21、numResource函数WnetEnumResource函数用于枚举网络资源。语法:DWORD WnetEnumResource(HANDLE hEnum,LPDWORD lpcCount,LPVOID lpBuffer,LPDWORD lpBufferSize);参数说明:hEnum由WnetOpenEnum函数的参数lphEnum传入,表示枚举的资源句柄lpcCount用来决定获取的资源数目最大值lpBuffer指向枚举结果存放的缓冲区地址lpBufferSize指向枚举结果存储缓冲区大小的变量地址 3WnetCloseEnum函数WnetCloseEnum函数用于结束一次枚举操作。语法
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 网络 聊天 编程
链接地址:https://www.31ppt.com/p-5452328.html