• :比较费工夫的一次实验,因为不熟悉VS的MFC程序开发流程;以此简单记录一下。
  • :仅为个人总结;如有错误,还望指教!

计算机网络实验八——聊天程序

HNU CS Computer Network Lab8

实验环境

Virtual Studio 2019

实验原理

详见实验指导书

实验步骤

0 环境搭建

  • 下载Visual Studio 2019
  • 安装MFC应用程序开发插件

也可直接下载旧版的VC++安装实验指导书完成,这里是本来就装了VS就懒得再下载了

1 创建工程

1、先建立一个MFC,选dialogBased,工程名为LX2 。


选择“高级功能”,选择“Window 套接字”

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

并对控件添加系统变量如下:


允许文本框输入回车,文本框右键选择“属性”

2、再建立一个MFC,选dialogBased,工程名为LX1。


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

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

**注意:**这个语句作用使发送按钮失效,以免还未连接用户就点击发送,发生不可预计的错误。

2 添加类和函数

为了在自己程序里面更自由地处理CSocket得到的消息,必须新建CSocket的派生类:在lx2工程里工作区类视图里点右键,添加新类:CServer,父类为CSocket。


如上所示,在lx2Dlg.h里添加头文件#include "CServer.h"和private变量:CServer m_server; CServer m_recv在对话框的图象上双击“侦听”按钮,在里面添加如下代码,使其如下所示:

void Clx2Dlg::OnBnClickedListen()
{m_server.Create(1000);             //  使用1000号端口m_server.Listen();                 //  侦听
}

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

void Clx2Dlg::OnBnClickedSend()
{UpdateData(TRUE);      //更新数据,使m_msg得到当前框中文本m_recv.Send(m_msg, 4 * m_msg.GetLength());   //发送数据m_ctrl.SetSel(0, -1);        //全选发送框文字m_ctrl.ReplaceSel(_T(""), TRUE);//将发送框置空
}

同样地,在Lx1工程里工作区类视图里右键,添加新类:CClient。继承自CSocket
在lx1Dlg.h里添加头文件#include "CClient.h"和private变量:CClient m_client;

双击对话框图象上的“连接”按钮,添加代码:

void Clx1Dlg::OnBnClickedConnect()
{UpdateData(TRUE);m_client.Create(1001);                //使用1001号端口if (m_client.Connect(m_ip, 1000))    //连接目标地址,1000端口{AfxMessageBox(_T("Client端连接成功"));m_send.EnableWindow(TRUE);            //连接成功,可以发送m_connect.EnableWindow(FALSE);        //同时禁止连接按钮}else{m_client.Close();                   //如果连接失败就关闭AfxMessageBox(_T("连接失败"));}
}

双击发送按钮,添加代码:

void Clx1Dlg::OnBnClickedSend()
{UpdateData(TRUE);          //更新数据,使m_msg得到当前框中文本m_client.Send(m_msg,4 * m_msg.GetLength());     //发送数据
}

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

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

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

在CSever.cpp中添加头文件#include "lx2Dlg.h"
添加OnAccept函数的代码:

void CSever::OnAccept(int nErrorCode)
{CSocket::OnAccept(nErrorCode);((Clx2Dlg*)(AfxGetApp()->m_pMainWnd))->ShowAccept();
}

这步以后,可以为Clx2Dlg类里添加public成员函数ShowAccept():

void Clx2Dlg::ShowAccept()
{m_server.Accept(m_recv);AfxMessageBox(_T("Server端连接成功"));m_send.EnableWindow(TRUE);          //  连接成功,可以发送m_listen.EnableWindow(FALSE);       //  同时禁止侦听按钮
}


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

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

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

void CSever::OnReceive(int nErrorCode)
{CSocket::OnReceive(nErrorCode);((Clx2Dlg*)(AfxGetApp()->m_pMainWnd))->ShowMsg();
}

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

void Clx2Dlg::ShowMsg()
{wchar_t buf[1024] = { '\0' };                   //声明为wchar_t类型!!!为了这个bug,我调了两个小时!哭晕了int len = m_recv.Receive(buf, 1024);            //接收消息到buf里面,长度1024字节。AfxMessageBox(buf);                                //用AfxMessageBox函数显示接收到的字符窜。
}

同样在lx1工程中也如此这般添加消息接收函数:

在CSever.cpp中添加头文件#include "lx1Dlg.h"
添加OnReceive函数的代码:

void CClient::OnReceive(int nErrorCode)
{CSocket::OnReceive(nErrorCode);((Clx1Dlg*)(AfxGetApp()->m_pMainWnd))->ShowMsg();
}

在Clx2Dlg里添加成员函数ShowMsg():

void Clx1Dlg::ShowMsg()
{wchar_t buf[1024] = { '\0' };                   //声明为wchar_t类型!!!int len = m_client.Receive(buf, 1024);           //接收消息到buf里面,长度1024字节。AfxMessageBox(buf);                                //用AfxMessageBox函数显示接收到的字符窜。
}

对于lx1和lx2工程,在对话框销毁的时候,关闭Socket连接,释放资源。

void Clx1Dlg::PostNcDestroy()
{CDialogEx::PostNcDestroy();m_client.Close();
}
void Clx2Dlg::PostNcDestroy()
{CDialogEx::PostNcDestroy();m_server.Close();m_recv.Close();
}

代码全部添加完毕。

3 运行测试

在两个vc中分别按下F5键,编译执行两个程序,就可以进行通信了。
程序运行过程如下:
1、在Lx2中按下侦听。
2、在Lx1中输入地址后按下连接。
3、 在Lx1的文本框内输入字符,按下发送,则Lx2端便会得到来自Lx1的消息。
4、在Lx2的文本框内输入字符,按下发送,则Lx1端便会得到来自Lx2的消息,同时Lx2的文本框会自动清空。


思考题

1、 改造程序结构:上面这个程序能做到双向发送消息。但是在这里,两个程序必须成对使用,即一个是Server端,一个是Client端。而真正实用的聊天程序即使使用了Client/Server模式,也必须将其整合,使其所有的功能都在一个程序中实现,以增加适用性。试改造结构,将两个程序的功能整合一起。界面参见第二题。

2、 添加程序功能,有以下几点可供参考:
用AfxMessageBox(…)显示消息显得不够专业,可以考虑制作一个双文本框的界面,让发送的消息在下面一个文本框中输入,接收的消息在上面的文本框中显示。
可以考虑在显示的文本框中添加滚动条让消息可以往下滚动。
增加保存聊天记录的功能。

3、此实验为了简单易操作,直接利用了CSocket类的Send和Receive进行通信。请参照实验原理部分的CSocketFile类和CArchive类的说明以及通信的流程图对其进行改造,以便更方便、高效地进行大量数据交换。

  • 1、2就是上面两个工程的组合
  • 蹲一个 3 的实现 ( 实在不想写了:( )

计算机网络实验八——聊天程序相关推荐

  1. Web开发及人机交互导论 实验八 JavaScript程序结构

    实验八 一.实验目的 二.实验环境 三.实验步骤 项目一:成绩百分制转换为五级制 项目二:计算∑n!\sum{n!}∑n! 项目三:系统常用函数的使用 项目四:课外拓展训练(一)--找出符合条件的数 ...

  2. 计算机网络课程设计之网络聊天程序的设计与实现

    前言 计算机网络课程设计开始,要求用C/C++,而且有些题目还要有图形界面,因此决定用Qt写图形界面,同时决定用一个程序完成所有的实验设计. 白嫖容易,创作不易,本文原创,转载请注明!!! 源码和可运 ...

  3. 【计算机网络】Socket聊天室程序

    计算机网络第一次实验报告 实验名称:Socket聊天室程序 实验内容 使用流式Socket设计聊天协议,聊天信息带有时间标签和类型标签,本报告中将说明交互消息的类型.语法.语义.时序等具体的消息处理方 ...

  4. 计算机网络——网络聊天程序的设计与实现

    计算机网络--网络聊天程序的设计与实现 一.实验目的 二.总体设计 1. 基本原理 2. 设计步骤 (1)服务器端编程的步骤 (2)客户端编程的步骤 三.详细设计 1. 程序流程图 2. 实验代码 ( ...

  5. 计算机网络课程设计聊天,计算机网络课程设计-简单聊天程序.doc

    计算机网络课程设计-简单聊天程序 黔南民族师范学院 计算机科学系 计算机网络课程设计报告 课题名称: 简单聊天程序 姓 名: 学 号: 专业班级: 系 (院): 计算机科学系 指导老师: 设计时间: ...

  6. Java实验:编写网络聊天程序(图形界面)

    课程名称 高级Java程序设计 实验项目 Java网络编程 实验目的: 使用客户机/服务器模式.基于TCP协议编写一对多"群聊"程序.其中客户机端单击"连接服务器&quo ...

  7. 计算机网络课程设计(一)网络聊天程序的设计与实现

    实验题目 网络聊天程序的设计与实现 实验目的 1.了解Socket通信的原理,学会使用Socket进行简单的网络编程,在此基础上编写一个聊天程序. 2.了解Qt编程,熟悉C++语言. 总体设计 1.背 ...

  8. 计算机网络实验4 - TCP套接字编程 - 点对点聊天 - 代码实现

    客户端 package chat;import java.io.IOException; import java.io.PrintStream; import java.net.Socket; imp ...

  9. 汇编语言(第三版)王爽著(实验八)分析一个奇怪的程序

    实验内容.程序清单及运行结果 分析下面的程序,在运行前思考:这个程序可以正确返回吗? 运行后思考:为什么会是这种结果? 通过这个程序加深对相关内容的理解. assume cs:codesg codes ...

最新文章

  1. 电脑端京东的我的订单html+css页面_什么是前端和后端开发?写给即将迈入前端开发领域的朋友...
  2. 数组名与数组指针的关系
  3. Okhttp-interceptor源码分析,快上车!
  4. Mybatis笔记一:java.lang.NoClassDefFoundError: org/apache/ibatis/mapping/DatabaseIdProvider
  5. Nhibernate学习教程(1)-- 开篇有益
  6. 文档声明和HTML样式表
  7. RestartOnCrash一个监控进程的小工具,可用于监控iis/apache/mysql等程序
  8. 官方华为鸿蒙os2.0,华为“新平板”6月2日登场,搭载麒麟9000,首发预装鸿蒙OS!...
  9. mongodb count 导致不正确的数量(mongodb count 一个坑)
  10. String类的流程控制
  11. 北航计算机考研计算机组成原理,北航计算机组成原理讲义.pdf
  12. 千脑——您的在线电脑
  13. 华为云计算IE证书培训费加考试费要2.5左右,值不值得考啊?
  14. 中传博士雷霄骅,致敬雷神,永远感谢雷神
  15. css样式calc的兼容性_在前端CSS3中使用calc()以及calc()的兼容性.
  16. 【其他】手机bilibili的视频文件在哪个目录
  17. job全异常 mapreduce_eclipse 运行MapReduce程序错误异常汇总(解决Map not fount)
  18. 【数据结构】初识时间空间复杂度
  19. Vue.js从0开始到实战开发1:通过简单案例从0开始了解Vue
  20. hiho一下 第139周 《买零食》 多维01背包

热门文章

  1. QQ空间将不再支持免费备份原图?附QQ空间相册导出工具合集
  2. vue路由传参到底有几种方式
  3. 如何实现密码的显示和隐藏?
  4. Python实现复数运算
  5. Python 中复数运算注意点
  6. c++ DFS练习 红与黑
  7. 上海第二家K11项目动工;v2food获近3.5亿元B+轮融资;华彬快消品贵州功能饮料生产基地投产...
  8. MTK Camera上电流程分析
  9. 打击标题党,痛斥灌水文
  10. 将文件转换为Base64格式