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 buffer[4096];

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

if (nRead == SOCKET_ERROR)

{

return;

}

buffer[nRead] = 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连接服务端

相关推荐
dragoooon3417 分钟前
[C++——lesson30.数据结构进阶——「红黑树」]
开发语言·数据结构·c++
云泽80818 分钟前
C++ STL 栈与队列完全指南:从容器使用到算法实现
开发语言·c++·算法
历程里程碑1 小时前
C++ 17异常处理:高效捕获与精准修复
java·c语言·开发语言·jvm·c++
xu_yule1 小时前
算法基础(背包问题)—分组背包和混合背包
c++·算法·动态规划·分组背包·混合背包
你的冰西瓜2 小时前
C++中的vector容器详解
开发语言·c++·stl
刻BITTER2 小时前
C++ 获取任意整数类型的最大、最小值和长度
开发语言·c++
程序员老舅2 小时前
C++ STL 算法:从原理到工程实践
linux·c++·stl·c/c++·数据结构与算法
十五年专注C++开发2 小时前
ZeroMQ: 一款高性能、异步、轻量级的消息传输库
网络·c++·分布式·zeroqm
superman超哥2 小时前
仓颉语言中循环语句(for/while)的深度剖析与工程实践
c语言·开发语言·c++·python·仓颉
chenyuhao20242 小时前
Linux系统编程:线程概念与控制
linux·服务器·开发语言·c++·后端