能运用 CAsyncSocket 类开发一个简单的网络聊天程序
时间: 2023-12-07 11:11:40 浏览: 74
当然可以!以下是一个使用 `CAsyncSocket` 类开发的简单的网络聊天程序示例:
```cpp
// ChatClientDlg.h
#pragma once
#include "afxsock.h"
class CChatClientDlg : public CDialogEx
{
public:
CChatClientDlg(CWnd* pParent = NULL);
enum { IDD = IDD_CHATCLIENT_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX);
protected:
HICON m_hIcon;
CAsyncSocket m_socket;
CString m_strServerIP;
UINT m_nServerPort;
CString m_strName;
void AppendMessage(LPCTSTR lpszMessage);
void OnReceive();
DECLARE_MESSAGE_MAP()
public:
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnBnClickedButtonConnect();
afx_msg void OnBnClickedButtonSend();
afx_msg void OnClose();
};
// ChatClientDlg.cpp
#include "stdafx.h"
#include "ChatClient.h"
#include "ChatClientDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CChatClientDlg::CChatClientDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(IDD_CHATCLIENT_DIALOG, pParent)
, m_strServerIP(_T("127.0.0.1"))
, m_nServerPort(12345)
, m_strName(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CChatClientDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT_SERVER_IP, m_strServerIP);
DDX_Text(pDX, IDC_EDIT_SERVER_PORT, m_nServerPort);
DDX_Text(pDX, IDC_EDIT_NAME, m_strName);
}
BEGIN_MESSAGE_MAP(CChatClientDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_CONNECT, &CChatClientDlg::OnBnClickedButtonConnect)
ON_BN_CLICKED(IDC_BUTTON_SEND, &CChatClientDlg::OnBnClickedButtonSend)
ON_WM_CLOSE()
END_MESSAGE_MAP()
BOOL CChatClientDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);
return TRUE;
}
void CChatClientDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
HCURSOR CChatClientDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CChatClientDlg::OnBnClickedButtonConnect()
{
if (!m_socket.Create())
{
AfxMessageBox(_T("Failed to create socket!"));
return;
}
if (!m_socket.Connect(m_strServerIP, m_nServerPort))
{
AfxMessageBox(_T("Failed to connect to server!"));
return;
}
CString strMessage;
strMessage.Format(_T("%s joined the chat."), m_strName);
m_socket.Send(strMessage, strMessage.GetLength() * sizeof(TCHAR));
GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(FALSE);
GetDlgItem(IDC_EDIT_SERVER_IP)->EnableWindow(FALSE);
GetDlgItem(IDC_EDIT_SERVER_PORT)->EnableWindow(FALSE);
GetDlgItem(IDC_EDIT_NAME)->EnableWindow(FALSE);
OnReceive();
}
void CChatClientDlg::OnBnClickedButtonSend()
{
CString strMessage;
GetDlgItemText(IDC_EDIT_MESSAGE, strMessage);
if (!strMessage.IsEmpty())
{
CString strFinalMessage;
strFinalMessage.Format(_T("%s: %s"), m_strName, strMessage);
m_socket.Send(strFinalMessage, strFinalMessage.GetLength() * sizeof(TCHAR));
SetDlgItemText(IDC_EDIT_MESSAGE, _T(""));
AppendMessage(strFinalMessage);
}
}
void CChatClientDlg::OnClose()
{
CString strMessage;
strMessage.Format(_T("%s left the chat."), m_strName);
m_socket.Send(strMessage, strMessage.GetLength() * sizeof(TCHAR));
m_socket.ShutDown();
CDialogEx::OnClose();
}
void CChatClientDlg::AppendMessage(LPCTSTR lpszMessage)
{
CString strMessage;
GetDlgItemText(IDC_EDIT_MESSAGES, strMessage);
strMessage += _T("\r\n");
strMessage += lpszMessage;
SetDlgItemText(IDC_EDIT_MESSAGES, strMessage);
}
void CChatClientDlg::OnReceive()
{
char szBuffer[1024];
int nReceived = m_socket.Receive(szBuffer, sizeof(szBuffer));
if (nReceived > 0)
{
szBuffer[nReceived] = 0;
AppendMessage(CString(szBuffer));
}
OnReceive(); // 继续等待下一条消息
}
```
这是一个简单的客户端,它通过 `CAsyncSocket` 类与服务器进行连接,并在连接成功后发送聊天消息。在收到聊天消息时,它将消息显示在 UI 上。
这个程序的 UI 包括一个编辑框(用于输入聊天消息)、一个发送按钮、一个服务器 IP 地址编辑框、一个服务器端口号编辑框、一个用户名编辑框、一个连接按钮和一个消息列表框。当用户输入用户名并按下连接按钮时,程序将尝试连接到服务器,并发送一个包含用户名的消息。当用户输入聊天消息并按下发送按钮时,程序将将消息发送到服务器。收到的聊天消息将显示在消息列表框中。
当用户关闭程序时,程序将发送一个包含用户名的消息,然后关闭网络连接。
请注意,这只是一个简单的示例,它并没有处理错误、异常情况或其他复杂情况。在实际的应用程序中,你需要更加谨慎地处理这些情况。
阅读全文