===============================================
MFC网络编程1
CAsyncSocket,Csocket, CArchive,和CSocketFile类
其中CArchive是对send和receive数据收发的封装,CSocketFile相当与将数据当作成一个标准文件一样处理,三者结合就相当于对本地文件的读写操作。
1.创建项目:windows 套接字
2.服务器端界面:
- 为控件关联变量:
IP Address Control --- CIPAddressCtrl m_ServerIP
Edit Control --- int m_Port
List Box --- CListBox m_ListWords
- 为button控件关联事件:
afx_msg void OnBnClickedButton2();//开始监听
afx_msg void OnBnClickedButton1();//停止监听
afx_msg void OnBnClickedButton3();//退出
- 分别为监听套接字和服务套接字添加类向导基类为CAsyncSocket:
注:((CchatserverDlg)(AfxGetApp()->m_pMainWnd)) -----为获取主窗口指针
class ListenSocket
//类内重写虚函数OnAccept
virtual void OnAccept(int nErrorCode);
//定义:由客户端发来的连接消息 触发的
void ListenSocket::OnAccept(int nErrorCode)
{
Accept(((CchatserverDlg*)(AfxGetApp()->m_pMainWnd))->m_ServerSocket);
((CchatserverDlg*)(AfxGetApp()->m_pMainWnd))->m_ServerSocket.AsyncSelect(FD_READ | FD_CLOSE);//阻塞监听读事件和客户端断开事件
((CchatserverDlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.AddString("接收了一个连接");
CAsyncSocket::OnAccept(nErrorCode);
((CchatserverDlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.SetTopIndex(
((CchatserverDlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.GetCount() - 1);
}
class ServerSocket
//类内重写虚函数OnRecieve,OnClose
virtual void OnReceive(int nErrorCode);
virtual void OnClose(int nErrorCode);
//定义:由客户端发来的发送消息 触发的
void ServerSocket::OnReceive(int ErrorCode)
{
char buf[50];
int n = Receive(buf, 50);
buf[n] = '\0';
CString buf1;
buf1.Format("收到:%s", buf);
((CchatserverDlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.AddString(buf1);
CAsyncSocket::OnReceive(ErrorCode);
((CchatserverDlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.SetTopIndex(
((CchatserverDlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.GetCount() - 1);
}
void ServerSocket::OnClose(int ErrorCode)
{
((CchatserverDlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.AddString("客户端已断开连接");
Close();
}
- 在chatserverDlg.h中添加类公有成员:
ListenSocket m_ListenSocket;
ServerSocket m_ServerSocket;
- 具体实现button事件:
void CchatserverDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码 开始监听:
BYTE nFild[4];
CString sIP, sPort;
m_ServerIP.GetAddress(nFild[0], nFild[1], nFild[2], nFild[3]);
sIP.Format("%d.%d.%d.%d", nFild[0], nFild[1], nFild[2], nFild[3]);
UpdateData();
sPort.Format("%d", m_Port);
m_ListenSocket.Create(m_Port, 1, FD_ACCEPT, sIP);
m_ListenSocket.Listen(1);
m_ListWords.AddString("在"+sIP+":"+sPort+"监听..."+"\n"+"等待连接");
((CchatserverDlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.SetTopIndex(
((CchatserverDlg*)(AfxGetApp()->m_pMainWnd))->m_ListWords.GetCount() - 1);
}
void CchatserverDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码 停止监听
m_ListenSocket.Close();
m_ListWords.AddString("监听结束");
}
void CchatserverDlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码 退出
CDialog::OnCancel();
}
3.客户端界面:
- 为控件关联变量:
IP Address Control --- CIPAddressCtrl m_ServerIP;
Edit Control --- int m_sPort;//顶上那个
Edit Control --- CString m_sWords;//底下那个
List Box --- CListBox m_LisrtWords;
- 为button控件关联事件:
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton2();
afx_msg void OnBnClickedButton3();
- 同样为连接套接字添加类向导基类为CAsyncSocket:
class CClientSocket
//重写虚函数OnConnect
virtual void OnConnect(int nErrorCode);
//定义:由服务器端发来的接受消息 触发的
void CClientSocket::OnConnect(int nErrorCode)
{
if (nErrorCode)
{
AfxMessageBox("连接失败,请您重试");
}
((CMFCApplication1Dlg*)(AfxGetApp()->m_pMainWnd))->m_LisrtWords.AddString("连接成功");
((CMFCApplication1Dlg*)(AfxGetApp()->m_pMainWnd))->m_LisrtWords.SetTopIndex(
((CMFCApplication1Dlg*)(AfxGetApp(5)->m_pMainWnd))->m_LisrtWords.GetCount() - 1);
}
- 在CMFCApplication1Dlg.h中添加类公有成员:
CClientSocket m_ClientSocket;
- 具体实现button事件:
void CMFCApplication1Dlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码 连接
BYTE nFild[4];
CString sIP;
UpdateData();
m_ServerIP.GetAddress(nFild[0], nFild[1], nFild[2], nFild[3]);
sIP.Format("%d.%d.%d.%d", nFild[0], nFild[1], nFild[2], nFild[3]);
m_ClientSocket.Create();
m_ClientSocket.Connect(sIP, m_sPort);
}
void CMFCApplication1Dlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码 断开
m_ClientSocket.Close();
m_LisrtWords.AddString("与服务器断开连接");
}
void CMFCApplication1Dlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码 发送
UpdateData();
m_ClientSocket.Send(m_sWords, m_sWords.GetLength());
m_LisrtWords.AddString("发送:" + m_sWords);
m_LisrtWords.SetTopIndex(m_LisrtWords.GetCount() - 1);
}