您好,欢迎来到九壹网。
搜索
您的当前位置:首页MFC实验报告

MFC实验报告

来源:九壹网
实验报告 学 号:

实验日期: 2013 年 05 月 18 日 姓 名: 总 分: 基于Socket和多线程编程的聊天程实验名称: 序实现 一、实验目的

1、熟悉Visual C++的基本操作。

2、基本了解基于对话框的windows应用程序的编写过程。 3、对于Windows Socket编程建立初步概念。

二、实验要求

1、应用Visual C++中MFC CSocket类,实现网络数据传输。 2、仿照本实验步骤,制作实用的局域网一对一聊天程序。

三、实验原理

注释 客户端 构造一个socket对1 CSocket m_server; CSocket m_client; 象 2 m_server.create(nport); 创建socket m_client.create(nport); 听等 与服务器 m_client.connect(straddr,nport); 3 m_server.listen(); 连接 建立连接 此时阻塞,等待服务器端侦听。 CSocket m_receive; m_server.accept(m_recei构造新的socket对4 ve); 象用以接收客户端 此时阻塞,等待客户机连的连接 接。 CSocketfile 5 构造一文件对象 CSocketfile file(&m_server); file(&m_server); CArchive arin CArchive arin (&file,CArchive::load); (&file,CArchive::load); 6 CArchive arout 构造流对象 CArchive arout (&file,(&file,CArchive::store); CArchive::store); 7 arin >>value; 用流进行数据的传arin >>value; 服务器端 arout<1.程序整体框架:主程序监听一端口,等待客户接入;同时构造一个线程类,准备接管会话。当一个Socket会话产生后,将这个会话交给线程处理,然后主程序继续监听。

2.客户端(Client)

客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个端口。

3.服务器端(Server)

服务器端,使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。

4.用户图形界面

用户图形界面方便程序与用户的交互,多个用户参加,完成会话功能,具体的设计要方便用户的使用,直观清晰,简洁明了,友好美观。

四、实验内容

一个最简单的点对点聊天程序

客户机/服务器模式是socket点对点网络程序典型的模式,以下这个实验就是实现一个简单的点对点通信的聊天程序。它用到的方法也是面向连接TCP连接的套接字MFC典型方式。其工作过程是:服务器首先启动,创建套接字后等待客户的连接;客户启动以后,创建套接字,然后和服务器建立连接;连接建立后,客户机和服务器可以通过建立的套接字连接进行信息通信。

先建立一个MFC,选dialogBased,设置工程名。

出现Dialog以后,编辑界面,使其如图所示并且对控件点击右键,选择属性选项,把每个控件的ID改掉(控件ID就是每个控件的名字,要改成有意义的,以便将来管理)。

各个控件的ID如下,并且在对话框画面点击右键,选Class Wizard选项,用这个工具对控件添加变量,使其图所示:

重新再VC中建立客户机工程,新建工程名

首先,在BOOL CLx1Dlg::OnInitDialog()和BOOL CLx2Dlg::OnInitDialog()末尾添加语句,使其如下所示:

m_send.EnableWindow(FALSE); //使发送按钮变灰

return TRUE; // return TRUE unless you set the focus to a control

为了在自己程序里面更自由地处理CSocket得到的消息,必须新建CSocket的派生类:

在第一个工程里工作区类视图里点右键,添加新类:CServer,父类为CSocket NewClass对话框如图所示:

在第一个工程里的Dlg.h添加 头文件#include \"Server.h\"

private变量:CServer m_server; CServer m_recv

在对话框的图象上双击“侦听”按钮,在里面添加如下代码,使其如下所示:

void CLx2Dlg::OnListen() {

m_server.Create(1000); // 使用1000号端口 m_server.Listen(); // 侦听 }

在对话框图象上再双击“发送”按钮,添加代码,如下所示: void CLx2Dlg::OnSend() {

UpdateData(TRUE); //更新数据,使m_msg得到当前框中文本 m_recv.Send(m_msg, 255); //发送数据

m_ctrl.SetSel(0, -1); //全选发送框文字 m_ctrl.ReplaceSel(\"\将发送框置空 }

同样地,在第一个工程里工作区类视图里右键,添加新类:CClient。继承自CSocket

在CLx1Dlg类里添加private变量:CClient m_client; 双击对话框图象上的“连接”按钮,添加代码: void CLx1Dlg::OnConnect() {

UpdateData(TRUE);

m_client.Create(1001); //使用1001号端口

if(m_client.Connect(m_ip, 1000)) //连接目标地址,1000端口 {

AfxMessageBox(\"Client端连接成功\");

m_send.EnableWindow(TRUE); //连接成功,可以发送 m_connect.EnableWindow(FALSE); //同时禁止连接按钮 } else {

m_client.Close(); //如果连接失败就关闭 AfxMessageBox(\"连接失败\"); } }

双击发送按钮,添加代码: void CLx1Dlg::OnSend() {

UpdateData(TRUE); //更新数据,使m_msg得到当前框中文本 m_client.Send(m_msg, 255); //发送数据,长度255字节 }

以上这些操作,已经将CSocket的建立,以及主机,客户机建立连接后的消息发送代码添加完成了,但是还缺少使其工作的消息机制。

下面的步骤就是利用OnAccept和OnReceive函数处理socket消息。

首先,在第一个工程的编辑界面点右键,选Class Wizard,在classname栏目里面找到CServer类,添加OnAccept和OnReceive函数并且双击下面的Member function栏目,分别为两个函数添加代码。

void CServer::OnAccept(int nErrorCode) {

// TODO: Add your specialized code here and/or call the base class CSocket::OnAccept(nErrorCode);

((CLx2Dlg*)(AfxGetApp()->m_pMainWnd))->ShowAccept();

//在这里仅仅添加了这一句,因为CLx2Dlg类是发送接收消息的主窗口,

//而且应用程序发送接收的消息也在CLx2Dlg对象实例中进行, //所以当CServer类的对象收到客户机的Connect消息时, //便可调用CLx2Dlg对象中的ShowAccept() 函数处理。 }

这步以后,可以在第一个工程里的Dlg类里添加public成员函数ShowAccept()。 void CLx2Dlg::ShowAccept() {

m_server.Accept(m_recv);

AfxMessageBox(\"Server端连接成功\");

m_send.EnableWindow(TRUE); // 连接成功,可以发送 m_listen.EnableWindow(FALSE); // 同时禁止侦听按钮 }

于是,当客户机调用m_client.Connect(m_ip, 1000);这句时,主机server端发现,并调用ShowAccept函数来建立连接。执行完以后,Socket连接便被建立。

接下来的工作便是添加发送聊天信息的函数了。

注意到前面点击发送按钮的OnSend() 函数已经添加好了,在Lx2工程中只要添加Server端的接收消息和显示消息功能就可以进行消息的传送。

在CServer类里像添加OnAccept() 一样添加成员函数OnReceive()。 void CServer::OnReceive(int nErrorCode) {

// TODO: Add your specialized code here and/or call the base class CSocket::OnReceive(nErrorCode);

((CLx2Dlg*)(AfxGetApp()->m_pMainWnd))->ShowMsg(); }

建立连接后,一方一旦发送数据,另一方的CSocket派生类便调用这个函数。其中代码可以参考前面OnAccept() 进行理解。

在CLx2Dlg里添加成员函数ShowMsg() void CLx2Dlg::ShowMsg() {

char buf[255];

m_recv.Receive(buf, 255); //接收消息到buf里面,长度255字节。

CString msg;

msg.Format(\"%s\", buf); //用AfxMessageBox函数显示接收到的字符窜。

AfxMessageBox(msg); //这里注意CString类的用法 }

同样在第二个工程中也如此这般添加消息接收函数 void CClient::OnReceive(int nErrorCode) {

// TODO: Add your specialized code here and/or call the base class ((CLx1Dlg*)(AfxGetApp()->m_pMainWnd))->ShowMsg(); CSocket::OnReceive(nErrorCode); }

void CLx1Dlg::ShowMsg() {

char buf[255];

m_client.Receive(buf, 255); //接收消息到buf里面,长度255字节。

CString msg;

msg.Format(\"%s\

AfxMessageBox(msg); //用AfxMessageBox函数显示接收到的字符窜。 }

销毁对话框,关闭Socket连接,释放资源。

以下为第二个工程

图1-11

void CLx1Dlg::OnDestroy() {

CDialog::OnDestroy(); m_client.Close(); //关闭套接字 }

在两个vc中分别按下F5键,编译执行两个程序。 程序运行过程如下:

1、在第一个工程中按下侦听。

2、在第二个工程中输入地址后按下连接。

3、在第二个工程的文本框内输入字符,按下发送,则第一个工程便会得到来自第二个工程的消息。

从而实现两个工程之间的通信对话,如图所示。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 91gzw.com 版权所有 湘ICP备2023023988号-2

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务