winsock多线程编程MFC
时间: 2023-06-28 13:05:13 浏览: 180
Winsock 是 Windows 操作系统提供的用于进行网络编程的 API,而 MFC 是基于 Win32 API 的一个 C++ 类库,用于快速开发 Windows 程序。在 MFC 中使用 Winsock 进行多线程编程,可以实现网络通信的并发处理。
下面是一个使用 MFC 和 Winsock 实现的简单的多线程网络程序的示例:
```cpp
// MySocket.h
class CMySocket : public CSocket
{
public:
CMySocket();
virtual ~CMySocket();
void SetParent(CWnd* pParentWnd);
void SetPort(UINT nPort);
void SetIPAddress(LPCTSTR lpszIPAddress);
protected:
virtual void OnReceive(int nErrorCode);
private:
CWnd* m_pParentWnd;
UINT m_nPort;
CString m_strIPAddress;
};
// MySocket.cpp
CMySocket::CMySocket()
{
m_pParentWnd = NULL;
m_nPort = 0;
m_strIPAddress.Empty();
}
CMySocket::~CMySocket()
{
}
void CMySocket::SetParent(CWnd* pParentWnd)
{
m_pParentWnd = pParentWnd;
}
void CMySocket::SetPort(UINT nPort)
{
m_nPort = nPort;
}
void CMySocket::SetIPAddress(LPCTSTR lpszIPAddress)
{
m_strIPAddress = lpszIPAddress;
}
void CMySocket::OnReceive(int nErrorCode)
{
if (nErrorCode == 0)
{
char szBuffer[1024];
int nBytes = Receive(szBuffer, sizeof(szBuffer));
if (nBytes > 0)
{
// 处理接收到的数据
CString strData(szBuffer, nBytes);
m_pParentWnd->SendMessage(WM_MY_SOCKET_RECEIVE, (WPARAM)this, (LPARAM)&strData);
}
}
CSocket::OnReceive(nErrorCode);
}
// MyThread.h
class CMyThread : public CWinThread
{
public:
CMyThread();
virtual ~CMyThread();
void SetParent(CWnd* pParentWnd);
void SetPort(UINT nPort);
protected:
virtual BOOL InitInstance();
virtual int ExitInstance();
private:
CWnd* m_pParentWnd;
UINT m_nPort;
};
// MyThread.cpp
CMyThread::CMyThread()
{
m_pParentWnd = NULL;
m_nPort = 0;
}
CMyThread::~CMyThread()
{
}
void CMyThread::SetParent(CWnd* pParentWnd)
{
m_pParentWnd = pParentWnd;
}
void CMyThread::SetPort(UINT nPort)
{
m_nPort = nPort;
}
BOOL CMyThread::InitInstance()
{
// 创建服务器端套接字
CMySocket socketServer;
socketServer.SetParent(m_pParentWnd);
socketServer.Create(m_nPort);
socketServer.Listen();
while (TRUE)
{
// 等待客户端连接
CMySocket* pSocketClient = new CMySocket;
pSocketClient->SetParent(m_pParentWnd);
socketServer.Accept(*pSocketClient);
// 创建客户端线程
CMyThread* pThreadClient = new CMyThread;
pThreadClient->SetParent(m_pParentWnd);
pThreadClient->SetPort(0);
pThreadClient->m_bAutoDelete = TRUE;
pThreadClient->CreateThread();
}
return TRUE;
}
int CMyThread::ExitInstance()
{
return CWinThread::ExitInstance();
}
// MyDialog.h
class CMyDialog : public CDialog
{
public:
CMyDialog(CWnd* pParent = NULL);
virtual ~CMyDialog();
enum { IDD = IDD_MY_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX);
virtual BOOL OnInitDialog();
afx_msg void OnBtnStart();
afx_msg void OnBtnStop();
afx_msg LRESULT OnSocketReceive(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
private:
CMyThread* m_pThreadServer;
CList<CMySocket*, CMySocket*> m_listSocketClient;
};
// MyDialog.cpp
BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
ON_BN_CLICKED(IDC_BTN_START, &CMyDialog::OnBtnStart)
ON_BN_CLICKED(IDC_BTN_STOP, &CMyDialog::OnBtnStop)
ON_MESSAGE(WM_MY_SOCKET_RECEIVE, &CMyDialog::OnSocketReceive)
END_MESSAGE_MAP()
CMyDialog::CMyDialog(CWnd* pParent /*=NULL*/)
: CDialog(CMyDialog::IDD, pParent)
{
m_pThreadServer = NULL;
}
CMyDialog::~CMyDialog()
{
}
void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
return TRUE;
}
void CMyDialog::OnBtnStart()
{
// 创建服务器线程
m_pThreadServer = new CMyThread;
m_pThreadServer->SetParent(this);
m_pThreadServer->SetPort(12345);
m_pThreadServer->m_bAutoDelete = TRUE;
m_pThreadServer->CreateThread();
}
void CMyDialog::OnBtnStop()
{
// 关闭服务器线程和所有客户端套接字
if (m_pThreadServer != NULL)
{
m_pThreadServer->PostThreadMessage(WM_QUIT, 0, 0);
m_pThreadServer = NULL;
}
POSITION pos = m_listSocketClient.GetHeadPosition();
while (pos != NULL)
{
CMySocket* pSocket = m_listSocketClient.GetNext(pos);
pSocket->Close();
delete pSocket;
}
m_listSocketClient.RemoveAll();
}
LRESULT CMyDialog::OnSocketReceive(WPARAM wParam, LPARAM lParam)
{
// 处理客户端套接字的接收事件
CMySocket* pSocket = (CMySocket*)wParam;
CString* pstrData = (CString*)lParam;
// 发送数据到客户端
pSocket->Send(pstrData->GetBuffer(), pstrData->GetLength());
return 0;
}
```
在上面的示例中,`CMySocket` 类继承自 `CSocket`,重载了 `OnReceive` 方法,处理套接字的接收事件,将接收到的数据发送给主窗口。`CMyThread` 类继承自 `CWinThread`,重载了 `InitInstance` 方法,创建服务器端套接字,并循环接收客户端连接,每次接收到客户端连接时创建一个客户端线程。`CMyDialog` 类继承自 `CDialog`,包含了开始和停止按钮,点击开始按钮创建服务器线程,点击停止按钮关闭服务器线程和所有客户端套接字,同时处理客户端套接字的接收事件,将接收到的数据发送回客户端。
阅读全文