MFC网络编程-Udp客户端

目录

1、UI的设计:

2、代码的实现:

(1)、重写CSocket虚函数OnReceive,并且传入对话框的指针

(2)、初始化SOCKET

(3)、绑定本地IP和端口

(4)、显示本地IP和端口在界面

(5)、进入房间事件

(6)、离开房间事件

(7)、发送信息事件

(8)、接收到数据的处理函数ProcessPendingRead

(9)、优化处理

1)、初始化默认服务端的端口和IP在框架的入口函数

2)、没有加入房间,发送按钮和退出按钮都不能点击

3)、初始化发送消息的EDIT只读,服务端IP和PORT可以修改

4)、加入房间之后重新设置按钮的状态

5)、离开房间重新设置按钮的状态

6)、重写框架类的关闭窗口函数,实现关闭窗口之后调用离开房间按钮事件。

3、最终的UI:


1、UI的设计:

2、代码的实现:

首先自定义一个类继承与CSocket类

(1)、重写CSocket虚函数OnReceive,并且传入对话框的指针

声明对话框类

class CUdpClientDlg;

传递指针

CClientSocket(CUdpClientDlg * pdlg);

CUdpClientDlg *m_pMainDlg;

CClientSocket::CClientSocket(CUdpClientDlg * pdlg)

{

m_pMainDlg = pdlg;

}

重写OnReceive函数实现底层的通信,并且自定义一个处理函数ProcessPendingRead

void CClientSocket::OnReceive(int nErrorCode)

{

// TODO: 在此添加专用代码和/或调用基类

CSocket::OnReceive(nErrorCode);

m_pMainDlg->ProcessPendingRead();

}

(2)、初始化SOCKET

//初始化SOCKET

m_pClientSocket = new CClientSocket(this);

m_pClientSocket->Create(0, SOCK_DGRAM);//使用数据报类型

(3)、绑定本地IP和端口

//绑定了本地IP和端口

CString strIP;

UINT uiPort;

m_pClientSocket->GetSockName(strIP, uiPort);

(4)、显示本地IP和端口在界面

SetDlgItemText(IDC_EDIT_LOAD_IP, strIP);

SetDlgItemInt(IDC_EDIT_LOAD_PORT, uiPort);

(5)、进入房间事件

获取服务端IP和端口

CString strIp;

UINT uiPort;

GetDlgItemTextW(IDC_EDIT_SERVER_IP, strIp);

uiPort = GetDlgItemInt(IDC_EDIT_SERVER_PORT);

进入房间发送enter

CString strEnterMsg("enter");

int nSead = m_pClientSocket->SendTo(strEnterMsg, strEnterMsg.GetLength() + 100, uiPort, strIp);

if (nSead == SOCKET_ERROR)

{

MessageBox(L"进入聊天室失败!");

return;

}

设置标志位

//设置标志位

m_EnterRoom = true;

(6)、离开房间事件

首先获取服务端IP和地址

CString strIp;

UINT uiPort;

GetDlgItemTextW(IDC_EDIT_SERVER_IP, strIp);

uiPort = GetDlgItemInt(IDC_EDIT_SERVER_PORT);

离开房间发送leave

CString strEnterMsg("leave");

int nSead = m_pClientSocket->SendTo(strEnterMsg, strEnterMsg.GetLength() + 100, uiPort, strIp);

if (nSead == SOCKET_ERROR)

{

MessageBox(L"离开聊天室失败!");

return;

}

设置标志位

m_bEnterRoom = true;

(7)、发送信息事件

获取服务端的地址

//获取服务端的地址

CString strIp;

UINT uiPort;

GetDlgItemTextW(IDC_EDIT_SERVER_IP, strIp);

uiPort = GetDlgItemInt(IDC_EDIT_SERVER_PORT);

发送数据

//发送数据

CString strMsg;

GetDlgItemText(IDC_EDIT_SEND_MESSAGE, strMsg);

m_pClientSocket->SendTo(strMsg, strMsg.GetLength() + 100, uiPort, strIp);

清空发送文本框

//清空

SetDlgItemText(IDC_EDIT_SEND_MESSAGE, L"");

(8)、接收到数据的处理函数ProcessPendingRead

CHAR buffer4096;

int nRead = m_pClientSocket->ReceiveFrom(buffer, 4096,NULL,NULL);

if (nRead == SOCKET_ERROR)

{

return;

}

buffernRead = L'\0';//字符串\0结尾所以要加上

CString strMsg(buffer);

CString alMsg;

GetDlgItemText(IDC_EDIT_CHAT_MESSAGE, alMsg);

SetDlgItemText(IDC_EDIT_CHAT_MESSAGE, alMsg + L"\r\n" + strMsg);

(9)、优化处理

1)、初始化默认服务端的端口和IP在框架的入口函数

//设置服务端默认的端口和IP

SetDlgItemText(IDC_EDIT_SERVER_IP, L"127.0.0.1");

SetDlgItemText(IDC_EDIT_SERVER_PORT, L"8080");

2)、没有加入房间,发送按钮和退出按钮都不能点击

//设置按钮初始化状态

GetDlgItem(IDC_BUTTON_OUT)->EnableWindow(FALSE);

GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(FALSE);

3)、初始化发送消息的EDIT只读,服务端IP和PORT可以修改

GetDlgItem(IDC_EDIT_SEND_MESSAGE)->EnableWindow(FALSE);

GetDlgItem(IDC_EDIT_SERVER_IP)->EnableWindow(TRUE);

GetDlgItem(IDC_EDIT_SERVER_PORT)->EnableWindow(TRUE);

4)、加入房间之后重新设置按钮的状态

//设置按钮文本框的状态

//设置按钮初始化状态

GetDlgItem(IDC_BUTTON_OUT)->EnableWindow(TRUE);

GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(TRUE);

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

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

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

5)、离开房间重新设置按钮的状态

GetDlgItem(IDC_BUTTON_OUT)->EnableWindow(FALSE);

GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(FALSE);

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

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

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

6)、重写框架类的关闭窗口函数,实现关闭窗口之后调用离开房间按钮事件。

BOOL CUdpClientDlg::DestroyWindow()

{

// TODO: 在此添加专用代码和/或调用基类

if (m_bEnterRoom)

{

OnBnClickedButtonOut();

}

return CDialogEx::DestroyWindow();

}

3、最终的UI:

实现UDP连接服务端

相关推荐
哥不想学算法22 分钟前
【C++】字符串字面量拼接
开发语言·c++
cookies_s_s6 小时前
C++ 字符串动态创建对象 -- 工厂模式、自动注册、模板递归动态调用
服务器·开发语言·c++
王老师青少年编程6 小时前
2026年6月GESP真题及题解(C++七级):消消乐
数据结构·c++·算法·真题·gesp·2026年6月
海清河晏1116 小时前
数据结构 | 二叉搜索树
数据结构·c++·visual studio
盐焗鹌鹑蛋7 小时前
【C++】继承
开发语言·c++
会周易的程序员7 小时前
使用 pybind11 封装 C++ 日志库 microLog 为 Python 模块
java·c++·python·物联网·架构·日志·aiot
WZF-Sang8 小时前
网络基础——2
服务器·网络·c++·学习·网络编程·php
-西门吹雪9 小时前
现代C++ 并发编程-学习指南
java·jvm·c++
没头脑的男大10 小时前
CMake学习教学
linux·c++·学习
aaPIXa62211 小时前
C++ TensorRT Edge-LLM 边缘推理框架:从原理到实战
开发语言·c++·edge