MFC-TCP网络编程客户端-Socket

news2024/12/29 9:50:33

目录

1、客户端创建流程:

2、UI设计:

3、代码实现:

(1)、ConnectSocket中重写OnReceive函数接收信息

(2)、框架类入口函数初始化

(3)、加入房间功能实现

(4)、离开房间功能实现

(5)、发送消息功能实现

(6)、OnPendingRead函数实现

4、最终运行结果:


1、客户端创建流程:

(1)、创建一个Socket对象并且自动绑定一个端口。

(2)、调用Connect()函数,建立一个到服务端的连接。

(3)、发送一个特殊消息进入房间enter。

(4)、使用Receive()函数,Send函数收发数据。

(5)、发送一个特殊消息退出房间leave。

2、UI设计:

3、代码实现:

(1)、ConnectSocket中重写OnReceive函数接收信息

CConnectSocket(CTcpClientDlg *pdlg);//框架类的指针,目的处理函数得放在框架中
    ~CConnectSocket();
    
    CTcpClientDlg * m_pMainDlg;
    virtual void OnReceive(int nErrorCode);

void CConnectSocket::OnReceive(int nErrorCode)
{
    // TODO: 在此添加专用代码和/或调用基类

    CSocket::OnReceive(nErrorCode);
    m_pMainDlg->OnPendingRead();//处理函数在框架中,因为显示在对话框中
}

(2)、框架类入口函数初始化

   //初始化服务端的IP,Port放在显示在UI

    SetDlgItemText(IDC_EDIT_SERVER_IP, L"127.0.0.1");
    SetDlgItemText(IDC_EDIT_SERVER_PORT, L"8080");

//设置各个按钮控件的状态

    GetDlgItem(IDC_BUTTON_ENTER_ROOM)->EnableWindow(TRUE);
    GetDlgItem(IDC_BUTTON_LEAVE_ROOM)->EnableWindow(FALSE);
    GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(FALSE);

//设置EDIT控件的只读或者可写

    ((CEdit*)GetDlgItem(IDC_EDIT_SEND_MESSAGE))->SetReadOnly(TRUE);
    ((CEdit*)GetDlgItem(IDC_EDIT_SERVER_PORT))->SetReadOnly(TRUE);
    ((CEdit*)GetDlgItem(IDC_EDIT_SERVER_IP))->SetReadOnly(TRUE);

(3)、加入房间功能实现

随机分配一个空闲的端口号

    // 创建tcp套接字并且绑定一个自动分配的端口号
        m_Pconnect = new CConnectSocket(this);
    m_Pconnect->Create();

把本地的IP和Port显示在UI

//获取本地的端口和IP,并显示在UI
    CString strlocalIP;
    UINT uilocalPort;
    m_Pconnect->GetSockName(strlocalIP, uilocalPort);
    SetDlgItemText(IDC_EDIT_LOCAL_IP, strlocalIP);
    SetDlgItemInt(IDC_EDIT_LOCAL_PORT, uilocalPort);

补充:建立TCP通讯的条件:

服务端和客户端的俩个端口得是空闲端口,客户端指定发送信息的IP地址,客户端在指定的IP上等待连接,同时还得有TCP\IP协议。

调用Connect连接服务端和客户端

    //调用connect函数连接服务端
    CString strServerIP;
    UINT uiServerPort;//服务端的IP和Port
    GetDlgItemText(IDC_EDIT_SERVER_IP, strServerIP);
    uiServerPort = GetDlgItemInt(IDC_EDIT_SERVER_PORT);

    if (!m_Pconnect->Connect(strServerIP, uiServerPort))
    {
        MessageBox(L"连接服务端失败");
        return;
    }

连接成功说明一个客户端加入房间

CString strEnterRoom = L"enter";
    m_Pconnect->Send(strEnterRoom, strEnterRoom.GetLength() + 100);
    m_bEnterRoom = TRUE;

界面的改变

GetDlgItem(IDC_BUTTON_ENTER_ROOM)->EnableWindow(FALSE);
    GetDlgItem(IDC_BUTTON_LEAVE_ROOM)->EnableWindow(TRUE);
    GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(TRUE);

    ((CEdit*)GetDlgItem(IDC_EDIT_SEND_MESSAGE))->SetReadOnly(FALSE);

(4)、离开房间功能实现

   CString strleaveRoom = L"leave";
    m_Pconnect->Send(strleaveRoom, strleaveRoom.GetLength() + 100);
    m_bEnterRoom = FALSE;

    GetDlgItem(IDC_BUTTON_ENTER_ROOM)->EnableWindow(TRUE);
    GetDlgItem(IDC_BUTTON_LEAVE_ROOM)->EnableWindow(FALSE);
    GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(FALSE);

    ((CEdit*)GetDlgItem(IDC_EDIT_SEND_MESSAGE))->SetReadOnly(TRUE);
    ((CEdit*)GetDlgItem(IDC_EDIT_SERVER_PORT))->SetReadOnly(FALSE);
    ((CEdit*)GetDlgItem(IDC_EDIT_SERVER_IP))->SetReadOnly(FALSE);

(5)、发送消息功能实现

发送消息给客户端

    // TODO: 在此添加控件通知处理程序代码
    CString strMsg;
    GetDlgItemText(IDC_EDIT_SEND_MESSAGE, strMsg);
    m_Pconnect->Send(strMsg, strMsg.GetLength() + 100);

    SetDlgItemText(IDC_EDIT_SEND_MESSAGE, L"");//将文本框清空方便下次输入

(6)、OnPendingRead函数实现

接收从客户端分发的消息

    TCHAR buff[4096];
    int nRead =m_Pconnect->Receive(buff, 4096);
    if (nRead == SOCKET_ERROR)
    {
        return;
    }
    buff[nRead] = L'\0';
    CString charMsg(buff);

    CString alMsg;
    GetDlgItemText(IDC_EDIT_CHAT_MESSAGE, alMsg);
    SetDlgItemText(IDC_EDIT_CHAT_MESSAGE, alMsg + L"\r\n" + charMsg);

4、最终运行结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1184875.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

新闻稿大纲怎么写框架?纯干货

新闻稿大纲在新闻报道中的重要性不言而喻,首先大纲能够提高写作效率,有了一份详细的大纲,可以帮助我们迅速组织思路,梳理采访内容,明确文章的结构和主题,避免在写作过程中出现不必要的拖延。 其次&#xf…

数据结构之AVL树

map/multimap/set/multiset这几个容器有个共同点是: 其底层都是按照二叉搜索树来实现的,但是普通的二叉搜索树有其自身的缺陷, 假如往树中插入的元素有序或者接近有序, 二叉搜索树就会退化成单支树, 时间复杂度会退化成O(N),因此map、set等关联式容器的底层结构是对二叉树进行了…

【 Docker: 数据卷挂载】

背景 Docker只提供了容器运行的必备依赖,但是一些编辑等操作的依赖是不支持的,如vi操作容器内部文件、将静态资源拷贝到容器内来等。 docker pull nginx docker run -d -p 81:80 --namemynginx -v D:/docker/nginx/www:/usr/share/nginx/www -v D:/dock…

性能测试资源监控宝藏工具:iDB Dashboard

iDB Dashboard 是 TiDB 自 4.0 版本起提供的图形化界面,可用于监控及诊断 TiDB 集群。TiDB Dashboard 内置于 TiDB 的 PD 组件中,无需独立部署: https://docs.pingcap.com/zh/tidb/v4.0/dashboard-intro

【GEE】8、Google 地球引擎中的时间序列分析【时间序列】

1简介 在本模块中,我们将讨论以下概念: 处理海洋的遥感图像。 从图像时间序列创建视频。 GEE 中的时间序列分析。 向图形用户界面添加基本元素。 2背景 深水地平线漏油事件被认为是有史以来最大的海上意外漏油事件。该井释放了超过 490 万桶石油&am…

实用知识(工作中常用)

mybatis-plus联表查询 pom.xml坐标 <!-- mybatis-plus-join --> <dependency><groupId>com.github.yulichang</groupId><artifactId>mybatis-plus-join</artifactId><version>1.2.4</version> </dependency>使用步骤&…

虚拟环境中使用的Python不是当前虚拟环境的,解决方法

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 在虚拟环境中使用的python和pip不是虚拟环境的pip安装不到当前的虚拟环境中…等 解决方法 1. 解决办法 打开配置文件 vim ~/.bashrc把如下代码注释即…

Gradle笔记 三 Gradle的项目周期和settings 文件

文章目录 项目的生命周期settings 文件 项目的生命周期 Gradle 项目的生命周期分为三大阶段: Initialization -> Configuration -> Execution. 每个阶段都有自己的职责,具体如下图所示: ● Initialization 阶段主要目的是初始化构建, 它又分为两个子过程,一个是执行 I…

刚柔相济铸伟业 ——访湖南顺新金属制品科技有限公司董事长张顺新

时代在变&#xff0c;唯初心不改。 精致、谦虚、谨慎、儒雅、温和——他就是张顺新&#xff0c;湖南顺新金属制品科技有限公司、湖南顺新供应链管理有限公司董事长&#xff0c;民建长沙市委常委&#xff0c;民建湖南省环资委副主任&#xff0c;省、市民建企联会常务副会长&…

加速度jsudo:小企业会遇到哪些瓶颈期?

什么是瓶颈期&#xff1f;瓶颈期&#xff0c;就是你无论怎么努力&#xff0c;成绩都是上不去&#xff0c;还是停留在原地&#xff1b;而自己表现的还是很匆忙&#xff0c;却不知道如何下手&#xff1f;就像水桶效益一样&#xff0c;水桶的木板高度层次不齐&#xff0c;像极了自…

如何使用Leangoo领歌管理Sprint Backlog

什么是Sprint Backlog&#xff1f; Sprint Backlog是Scrum的主要工件之一。在Scrum中&#xff0c;团队按照迭代的方式工作&#xff0c;每个迭代称为一个Sprint。在Sprint开始之前&#xff0c;PO会准备好产品Backlog&#xff0c;准备好的产品Backlog应该是经过梳理、估算和优先…

STM32笔记—定时器

目录 一、TIM简介 二、基本定时器&#xff08;TIM6和TIM7&#xff09; 1. TIM6和TIM7简介 2. TIM6和TIM7的主要特性 3. TIM6和TIM7的功能 3.1 时基单元 3.2 计数模式 3.3 时钟源 三、通用定时器 1. TIMx(2、3、4、5)简介 2. TIMx主要功能 3. 时钟选择 4. 影子寄存器…

湖泊河道水质蓝藻浮漂监测案例

湖泊河道水质蓝藻浮漂监测案例 湖泊和河道的浮漂水质监测和蓝藻治理是现代城市环境管理的重要内容之一。随着人类社会的发展&#xff0c;水污染问题越来越严重&#xff0c;而湖泊和河道作为水资源的重要组成部分&#xff0c;其水质的变化和污染程度直接关系到人们的生命安全和…

qt+opengl 三维坐标系(三)

文章目录 前言一、深度测和投影矩阵、观察矩阵二、绘制坐标系三、添加箭头四、添加文字五、放大缩小六、旋转七、移动八、完整代码总结 前言 效果如图 一、深度测和投影矩阵、观察矩阵 这部分不明白&#xff0c;网上查的都是这个步骤&#xff0c;用起来也没问题。 void MOp…

avue 表单自定义标题无效问题(avue 表单自定义标题,当prop含有大写字母时失效)

问题描述&#xff1a; avue 表单自定义标题&#xff0c;官方文档可以生效&#xff0c;项目中不生效。多方排查发现&#xff0c;当prop含有大写字母时失效。 代码展示&#xff1a; <avue-form v-model"form" :option"option"><template #classN…

腾讯待办关停后,导出的ics文件怎么导入iPhone手机日历?

ics文件是一种通用日历格式保存的日历文件&#xff0c;不少提醒待办类软件支持导出ics文件&#xff0c;诸如大家所熟知的腾讯待办就支持导出成ics文件&#xff0c;腾讯待办的主要功能一待办事项和日程管理位置&#xff0c;设置好时间提醒后&#xff0c;可通过公众号端口弹出提醒…

c语言练习第10周(1~5)

根据公式求和 输入样例20输出样例 534.188884 #include<stdio.h> #include<math.h> int main() {int i,n;scanf("%d", &n);double s 0,t0;for (i 1; i < n; i) {t t sqrt(i);s s t;}printf("%.6lf", s);return 0; } 第一行输入…

STA——绪论

一、概述 静态时序分析&#xff08;简称STA&#xff09;是用来验证数字设计时序的技术之一&#xff0c;另外一种验证时序的方法是时序仿真&#xff0c;时序仿真可以同时验证功能和时序。“时序分析”这个术语就是用来指代“静态时序分析“或”时序仿真“这两种方法之一&#xf…

uniapp H5预览PDF支持手势缩放、分页、添加水印、懒加载、PDF下载

效果预览 项目说明 uniapp vue2 node&#xff1a;v14.18.3 npm&#xff1a; 6.14.15 安装pdfh5.js插件 pdfh5 - npm (npmjs.com)pdfh5.js 基于pdf.js和jQuery pdfh5 - npm (npmjs.com) npm install pdfh5 由于我安装最新的pdfh5.js后运行时报错 所以我选择降低版本,可能是node…

太细了:美团一面连环夺命20问,搞定就60W起

说在前面 在40岁老架构师尼恩的&#xff08;50&#xff09;读者社群中&#xff0c;经常有小伙伴&#xff0c;需要面试美团、京东、阿里、 百度、头条等大厂。 下面是一个小伙伴成功拿到通过了美团一面面试&#xff0c;现在把面试真题和参考答案收入咱们的宝典。 通过美团一面…