MFC-TCP网络编程服务端-Socket
目录
1、通过Socket建立服务端:
2、UI设计:
3、代码的实现:
(1)、CListenSocket类
(2)、CConnectSocket类
(3)、CTcpServerDlg类
1、通过Socket建立服务端:
(1)、创建一个Socket对象并绑定一个端口:CListenSocket 监听Socket
(2)、通过Listen()函数,监听来自客户端的连接请求
(3)、连接请求到来之后,建立一个通信用的Socket,CConnectSocket,并且加入数组中
(4)、使用Send()、Receive()函数,接收客户端发送的数据,并遍历数组,一次转发消息
2、UI设计:

3、代码的实现:
(1)、CListenSocket类
CListenSocket的目的是等待客户端的连接请求,继承Socket类,重写Socket的OnAccept函数,创建Socket对象,连接的初始化和等待客户端连接。
CListenSocket.h中
CListenSocket(CTcpServerDlg * pdlg);//传递对话框的指针
~CListenSocket();
virtual void OnAccept(int nErrorCode);//重写父类
CTcpServerDlg *m_pMainDlg;//接收传递的对话框指针
CListenSocket.cpp中
CListenSocket::CListenSocket(CTcpServerDlg * pdlg)
{
m_pMainDlg = pdlg; //初始化接收的对话框指针
}
void CListenSocket::OnAccept(int nErrorCode)
{
// TODO: 在此添加专用代码和/或调用基类CSocket::OnAccept(nErrorCode);
m_pMainDlg->ProcessPendingAccept();//对于连接函数的处理放在对话框函数中处理
}
(2)、CConnectSocket类
CConnectSocket的目的是通讯用的Socket,继承Socket类,重写Socket的OnReceive函数,数据的接收和处理以及数据的解析。
CConnectSocket.h中
CConnectSocket(CTcpServerDlg *pdlg);
~CConnectSocket();
virtual void OnReceive(int nErrorCode);
CTcpServerDlg *m_pMainDlg;
CConnectSocket.cpp中
CConnectSocket::CConnectSocket(CTcpServerDlg *pdlg)
{
m_pMainDlg = pdlg;
}
void CConnectSocket::OnReceive(int nErrorCode)
{
// TODO: 在此添加专用代码和/或调用基类CSocket::OnReceive(nErrorCode);
m_pMainDlg->ProcessPendingRead(this);//接收消息必须要传递指针进去,调用接收函数
}
(3)、CTcpServerDlg类
1)、声明服务端用于监听的socket
//服务端声明的用于监听的socket
CListenSocket *m_pListenSocket;
2)、声明一个CArray的对象,里面存放的CConectSocket指针
CArray<CConnectSocket*, CConnectSocket*&>m_ConnectSocketList;
//m_ConnectSocketList是CArray的一个对象,里面放着CConnectSocket的指针,并且可以对里面的数据进行访问和修改。
// CConnectSocket*&当数组元素被传递给函数时,使用引用方式传递元素,可以有效避免不必要的拷贝和内存开销。
3)、定义一个结构体,保存客户端的IP和Port
struct ClientAddr
{
CString strIp;
UINT uiPort;
};
4)、框架类的入口函数初始化监听Socket和端口号
m_pListenSocket = new CListenSocket(this);
//m_pListenSocket用来监听服务器的连接所以要分配内存
m_pListenSocket->Create(8080);
//初始化端口号
if (!m_pListenSocket->Listen())
{
MessageBox(L"监听失败!");
return FALSE;
}
5)、实现ProcessPendingAccept()函数
主要实现监听服务器的连接,监听到了就加到列表中
CConnectSocket *pConnectSocket = new CConnectSocket(this);
if (m_pListenSocket->Accept(*pConnectSocket))
{
m_ConnectSocketList.Add(pConnectSocket);
}
else {
delete pConnectSocket;
}
6)、实现ProcessPendingRead()函数
数据的接收,并且存放在buff中
TCHAR buff[4096];//存放接收到的数据
//接收数据
int nRead = connectSocket->Receive(buff, 4096);
if (nRead == SOCKET_ERROR)
{
return;
}buff[nRead] = L'\0';//接收到的数据末尾加上结束符
CString strTemp(buff);//格式化buff
把连接到的客户端IP和Port存放在结构体中
ClientAddr clientAddr;//用来存放客户端的IP和Port
//获取连接上来的客户端的IP和端口
connectSocket->GetPeerName(clientAddr.strIp, clientAddr.uiPort);
解析数据:加入房间enter
int i = 0;
//解析数据
if (strTemp.CompareNoCase(L"enter") == 0)
{
//通知其他客户端有人进入房间
CString strEnterMsg;
strEnterMsg.Format(L"系统消息:%s(%d)进入了房间", clientAddr.strIp, clientAddr.uiPort);
for ( i;i<m_ConnectSocketList.GetSize();i++)
{//遍历每一个客户端,并且发送消息给每个客户端。
CConnectSocket *& tempClient = m_ConnectSocketList.ElementAt(i);
tempClient->Send(strEnterMsg, strEnterMsg.GetLength() + 100);
}
显示到界面
//更新界面
SetDlgItemInt(IDC_EDIT_NUMBER, m_ConnectSocketList.GetSize());//显示当前客户端人数CString ALmSG;
GetDlgItemText(IDC_EDIT_MESSAGE, ALmSG);//EDIT上显示的之前的消息
SetDlgItemText(IDC_EDIT_MESSAGE, ALmSG + L"\r\n" + strEnterMsg);
//显示的现在的消息加上之前的消息
解析数据:离开房间leave
//从列表中移除
for (i;i<m_ConnectSocketList.GetSize();i++)
{
CConnectSocket *&temClient = m_ConnectSocketList.ElementAt(i);
ClientAddr temClientAddr;
temClient->GetPeerName(temClientAddr.strIp, temClientAddr.uiPort);
if (temClientAddr.uiPort == clientAddr.uiPort && temClientAddr.strIp.Compare(clientAddr.strIp) == 0)
{//当前移除的IP和Port如果和加入的时候存放在结构体的一样直接跳出循环删除
break;
}
if (i<m_ConnectSocketList.GetSize())
{
m_ConnectSocketList.RemoveAt(i);
}
发送给每一个客户端消息
//通知所有人
CString strleaveMsg;
strleaveMsg.Format(L"系统消息:%s(%d)进入了房间", clientAddr.strIp, clientAddr.uiPort);
for (i; i < m_ConnectSocketList.GetSize(); i++)
{
CConnectSocket *& tempClient = m_ConnectSocketList.ElementAt(i);
tempClient->Send(strleaveMsg, strleaveMsg.GetLength() + 100);
}
更新界面
//更新界面
SetDlgItemInt(IDC_EDIT_NUMBER, m_ConnectSocketList.GetSize());CString ALmSG;
GetDlgItemText(IDC_EDIT_MESSAGE, ALmSG);
SetDlgItemText(IDC_EDIT_MESSAGE, ALmSG + L"\r\n" + strleaveMsg);
发送的是普通消息
//遍历每一个客户端发出,然后更新界面即可
CString strMsg;
strMsg.Format(L"%s(%d):%s", clientAddr.strIp, clientAddr.uiPort,strTemp);
for (i; i < m_ConnectSocketList.GetSize(); i++)
{
CConnectSocket *& tempClient = m_ConnectSocketList.ElementAt(i);
tempClient->Send(strMsg, strMsg.GetLength() + 100);
}
//更新界面
SetDlgItemInt(IDC_EDIT_NUMBER, m_ConnectSocketList.GetSize());CString ALmSG;
GetDlgItemText(IDC_EDIT_MESSAGE, ALmSG);
SetDlgItemText(IDC_EDIT_MESSAGE, ALmSG + L"\r\n" + strMsg);
相关文章:
MFC-TCP网络编程服务端-Socket
目录 1、通过Socket建立服务端: 2、UI设计: 3、代码的实现: (1)、CListenSocket类 (2)、CConnectSocket类 (3)、CTcpServerDlg类 1、通过Socket建立服务端ÿ…...
ChatGPT辅助下的小组学习
1 网上分享会-主题 1.9曾子曰:“慎终追远,民德归厚矣。” Master Zeng said:“Be circumspect in funerary services and continue sacrifices to the distant ancestors, and the virtue (de 德) of the common people will thrive.” 2 过程记录 听…...
Linux相关命令
切换root用户:sudo su 串口功能测试:cutecom 某某驱动查询:nvidia-smi #xxx-smi查询某某驱动 在线安装某某程序:apt install xxx 设置文件权限chmod 常用:chmod 777 sudo chmod 600 (只有所有者…...
详解卷积神经网络结构
前言 卷积神经网络是以卷积层为主的深度网路结构,网络结构包括有卷积层、激活层、BN层、池化层、FC层、损失层等。卷积操作是对图像和滤波矩阵做内积(元素相乘再求和)的操作。 1. 卷积层 常见的卷积操作如下: 卷积操作解释图解…...
java读取pdf数据
目录 读取方式有两种: 方式一: 方式一所需要的maven依赖如下: 方式一读取的Java代码如下:<...
arcmap / arcgis 安装教程
ArcGIS 10.8 for Desktop 完整安装教程(含win7/8/10 32/64位下载地址亲测可用汉化) | 麻辣GIS (malagis.com) 关于GIS语言汉化包(中文)安装失败的解决办法_arcgis中文语言包_miumiuniya的博客-CSDN博客 检查安装路径:…...
CMake中的变量: 改变构建行为的变量
文章目录 变量名称描述BUILD_SHARED_LIBS全局标志,用于在启用时使add_library()创建共享库。 如果存在并且为true,则这将导致所有库被构建为共享库,除非该库被明确添加为静态库。这个变量通常作为option()添加到项目中,这样项目的…...
台式电脑怎么无损备份迁移系统到新硬盘(使用傲梅,免费的就可以)
文章目录 前言一、想要将源硬盘上的系统原封不动地迁移到新硬盘上二、准备工作2.具体步骤 总结 前言 半路接手公司一台台式电脑,C盘(120g)爆红,仅剩几个G,优化了几次,无果后。准备换一个大一点的增到500g。…...
【紫光同创国产FPGA教程】【PGC1/2KG第七章】7.数字钟实验例程
本原创教程由深圳市小眼睛科技有限公司创作,版权归本公司所有,如需转载,需授权并注明出处 适用于板卡型号: 紫光同创PGC1/2KG开发平台(盘古1K/2K) 一:盘古1K/2K开发板(紫光同创PGC…...
【星海随笔】git的使用
1.在终端,检查git是否安装 git --version 2.没有安装的话去,官网,下载git 3.一直点下一步即可 4.安装后在终端检查git是否安装好 5.设置用户名和邮件地址(最好和GitHub的用户名/邮箱保持一致) git config --global user.name “自己的用户名”…...
安卓常见设计模式------装饰器模式(Kotlin版)
1. W1 是什么,什么是装饰器模式? 思想:动态地给对象添加额外的功能,通过将对象包装在一个装饰器类中,使装饰器类在不改变原始对象结构的情况下,扩展其功能。 2. W2 为什么,为什么需要使用装饰…...
将网站上的点击作为转化操作进行跟踪-官方指导文档
您可以使用转化跟踪功能,在用户点击您网站上的某个按钮或链接时进行跟踪。例如,您可以在用户点击“立即购买”按钮或点击您移动网站上的电话号码时进行跟踪。 本文介绍如何添加和修改转化跟踪代码,以便跟踪客户在您网站上的点击操作。如果希…...
Go相关命令说明
目录 Go相关命令说明go mod tidy :清理未使用依赖项,并更新模块文件主要功能好处 go clean -modcache :清除模块缓存go clean -testcache :清除测试缓存go test -v ./client :测试当前目录下client目录中的所有测试函数…...
3D全景技术,为我们打开全新宣传领域
随着科技的发展,3D全景技术正在融入我们的生活,这种全新视觉体验方式为我们打开了一扇全新的宣传领域,可以让我们多方位、多视角地探索各个行业,无论是对教育、商业、还是其他领域,都产生了深远的影响。 3D全景技术结合…...
【3D 图像分割】基于 Pytorch 的 VNet 3D 图像分割10(测试推理篇)
对于直接将裁剪的patch,一个个的放到训练好的模型中进行预测,这部分代码可以直接参考前面的训练部分就行了。其实说白了,就是验证部分。不使用dataloader的方法,也只需要修改少部分代码即可。 但是,这种方法是不end to end的。我们接下来要做的,就是将一个CT数组作为输入…...
PyCharm+Miniconda3安装配置教程
PyCharm是Python著名的Python集成开发环境(IDE) conda有Miniconda和Anaconda,前者应该是类似最小化版本,后者可能是功能更为强大的版本,我们这里安装Miniconda 按官方文档的说法conda相当于pip与virtualenv的结合&am…...
【慢SQL性能优化】 一条SQL的生命周期 | 京东物流技术团队
一、 一条简单SQL在MySQL执行过程 一张简单的图说明下,MySQL架构有哪些组件和组建间关系,接下来给大家用SQL语句分析 例如如下SQL语句 SELECT department_id FROM employee WHERE name Lucy AND age > 18 GROUP BY department_id其中name为索引&a…...
小程序day05
使用npm包 Vant Weapp 类似于前端boostrap和element ui那些的样式框架。 安装过程 注意:这里建议直接去看官网的安装过程。 vant-weapp版本最好也不要指定 在项目目录里面先输入npm init -y 初始化一个包管理配置文件: package.json 使用css变量定制vant主题样式࿰…...
Docker两个容器互相请求接口
BEGIN 环境:Docker-Windows-Hyperf 1. 过以下命令查看Docker中的所有网络 docker network ls这个命令会列出所有的Docker网络,包括其ID、名称、驱动以及作用范围 在 Docker 中,容器通过 Docker 网络进行相互通信;在 Docker 中有…...
UML与PlantUML简介
UML与PlantUML 1、UML与PlantUML概述2、PlantUML使用 1、UML与PlantUML概述 UML(Unified Modeling Language)是一种统一建模语言,为面向对象开发系统的产品进行说明、可视化、和编制文档的一种标准语言,独立于任何具体程序设计语言…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...
脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...
什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...
