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连接服务端

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值