MFC网络编程 — 指针对应C语言 NOTE14
通过类对象指针调用类的方法:
在MySocket类定义CChatServerDlg * m_dlg 可以方便调用ChatServerDlg类的各种方法,替代原来的 ((CchatserverDlg*)(AfxGetApp()->m_pMainWnd))
函数原型:(类CAsyncSocket 的TCP部分 )
#define SOCK_STREAM 1 /* stream socket */
#define SOCK_DGRAM 2 /* datagram socket */
1. BOOL Create(UINT nSocketPort = 0, int nSocketType=SOCK_STREAM,
long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE,
LPCTSTR lpszSocketAddress = NULL);
2. BOOL Listen(int nConnectionBacklog=5);
3. virtual BOOL Accept(CAsyncSocket& rConnectedSocket,
SOCKADDR* lpSockAddr = NULL, int* lpSockAddrLen = NULL);
4. BOOL Connect(LPCTSTR lpszHostAddress, UINT nHostPort);
5. BOOL AsyncSelect(long lEvent =
FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
6. virtual int Send(const void* lpBuf, int nBufLen, int nFlags = 0);
7. virtual int Receive(void* lpBuf, int nBufLen, int nFlags = 0);
8. virtual void OnReceive(int nErrorCode);
9. virtual void OnSend(int nErrorCode);
10. virtual void OnOutOfBandData(int nErrorCode);
11. virtual void OnAccept(int nErrorCode);
12. virtual void OnConnect(int nErrorCode);
13. virtual void OnClose(int nErrorCode);
开始监听:
void CChatServerDlg::OnListenBtn()
{
m_ListenSocket = new MySocket;
m_ListenSocket->GetDlg(this);
UpdateData();
BYTE nFild[4];
ServerIP.GetAddress(nFild[0], nFild[1], nFild[2], nFild[3]);
CString sIP;
sIP.Format("%d.%d.%d.%d", nFild[0], nFild[1], nFild[2], nFild[3]);
CString sPort;
sPort.Format("%d", Port);
m_ListenSocket->Create(Port, SOCK_STREAM, FD_ACCEPT, sIP);
m_ListenSocket->Listen(5);
m_ListWords.AddString("正在" + sIP + ":" + sPort + "处监听");
}
void MySocket::GetDlg(CChatServerDlg *dlg)
{
m_dlg = dlg;
}
接收到客户端连接请求会触发:(m_ListenSocket的) OnAccept()事件。
void MySocket::OnAccept(int nErrorCode)
{
m_dlg->OnAccept();
CAsyncSocket::OnAccept(nErrorCode);
}
调用(主窗口CChatServerDlg的 )OnAccept()函数:
void CChatServerDlg::OnAccept()
{
m_ServerSocket = new MySocket;
m_ServerSocket->GetDlg(this);
m_ListenSocket->Accept(*m_ServerSocket);
m_ServerSocket->AsyncSelect(FD_READ | FD_CLOSE);
m_ListWords.AddString("接收到一个连接");
}
接收到客户端发来的消息会触发(m_ServerSocket的) OnReceive()事件,即是上面的 FD_READ
void MySocket::OnReceive(int nErrorCode)
{
m_dlg->OnReceive();
CAsyncSocket::OnReceive(nErrorCode);
}
调用(主窗口CChatServerDlg的 ) OnRecieve()函数:
void CChatServerDlg::OnReceive()
{
char buffer[100];
int n = m_ServerSocket->Receive(buffer, 100);
buffer[n] = '\0';
CString buffer1;
buffer1.Format("收到:%s", buffer);
m_ListWords.AddString(buffer1);
m_LisrWords.SetTopIndex(m_ListWords.GetCount()-1);
}
客户端主动断开连接会触发(m_ServerSocket的) OnClose()事件:
void MySocket::OnClose(int nErrorCode)
{
m_dlg->OnClose();
CAsyncSocket::OnClose(nErrorCode);
}
调用(主窗口CChatServerDlg的 ) OnClose()函数:
void CChatServerDlg::OnClose()
{
m_ServerSocket->Close();
delete m_ServerSocket;
m_ServerSocket = NULL;
m_ListWords.AddString("客户端已断开连接");
}
停止监听:
void CChatServerDlg::OnStopBtn()
{
m_ListenSocket->Close();
delete m_ListenSocket;
m_ListenSocket = NULL;
m_ServerSocket->Close();
delete m_ServerSocket;
m_ServerSocket = NULL;
m_ListWords.AddString("已停止监听");
}
问题描述:
1>e:\xxno\vs2010网络编程教程-程序\axien\指针版服务端\chatserver\chatserver\mysocket.h(12): error C2143: 语法错误: 缺少“;”(在“*”的前面)
1>e:\xxno\vs2010网络编程教程-程序\axien\指针版服务端\chatserver\chatserver\mysocket.h(12): error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int
1>e:\xxno\vs2010网络编程教程-程序\axien\指针版服务端\chatserver\chatserver\mysocket.h(12): error C2238: 意外的标记位于“;”之前
1>e:\xxno\vs2010网络编程教程-程序\axien\指针版服务端\chatserver\chatserver\mysocket.h(13): error C2061: 语法错误: 标识符“CChatServerDlg”
解决:添加类声明 class CChatServerDlg;
List Box控件 SetTopIndex(GetCount()-1) 无效
解决:List Box 属性的Sort 设置为false。
演示效果:
修改图标:
阿里矢量图 下载相应的Png图 大小为48*48,在线格式转换为ico格式,在资源视图icon子目录项添加资源即可。
代码修改位置:
m_hIcon = AfxGetApp()->LoadIcon(xxx);xxx为资源ico图片ID
基于CSocket类的网络编程,使用CSocketFile类和CArchive类一起管理数据的发送和接收,就像对某个文件CFile进行操作,简化数据的收发。方法:创建一个与CSocket关联的CSocketFile对象,创建一个与CSocketFile关联的CArchive对象,并指定CArchive对象用与读或者写。
....
CArchive * m_archiveIn;
CArchive * m_archiveOut;
CSocketFile * m_socketfile;
....
m_socketfile=new CSocketFile(m_ServerSocket);
m_archiveIn=new CArchive(m_socketfile,CArchive::load);
m_archiveOut=new CArchive(m_socketfile,CArchive::store);
....发送:
*m_archiveOut<<m_sWords;
m_archiveOut->Flush();
....接收:
*m_archiveIn>>m_Input;
m_archiveIn->Flush();