18.4.3 使用WinSock类设计网络聊天室
在18.3.3节中介绍了如何使用套接字函数设计网络聊天室,下面将使用WinSock类来设计一个网络聊天程序。程序依然由两个实例组成,即服务器端和客户端。服务器端接受连接并转发信息,客户端负责连接服务器,并发送信息。
服务器端程序设计步骤如下。
ch1808实例位置:mr\18\sl\08
(1)创建一个基于对话框的工程,设计对话框资源如图18.16所示。
图18.16 服务器端资源设计窗口
(2)从CSocket类派生一个新类CClientSocket,在头文件中引用对话框的头文件和afxsock.h头文件,并对对话框类进行前导声明。
(3)处理“监听”按钮的单击事件,开始监听客户端。
void CServerDlg::OnOK() { this->UpdateData(); m_pSocket = new CServerSocket(this); if (!m_pSocket->Create(70)) { MessageBox("套接字创建失败"); delete m_pSocket; m_pSocket = NULL; return; }if (!m_pSocket->Listen()) MessageBox("监听失败"); }
|
(4)在对话框中添加AcceptConnect方法,用于接受客户端的连接。
void CServerDlg::AcceptConnect() { CClientSocket* socket = new CClientSocket(this); //接受客户端的连接 if (m_pSocket->Accept(*socket)) m_socketlist.AddTail(socket); else delete socket; }
|
(5)在对话框中添加ReceiveData方法,用于接收客户端传来的数据。
void CServerDlg::ReceiveData(CClientSocket* socket) { char bufferdata[BUFFERSIZE];//接收客户端传来的数据 int result = socket->Receive(bufferdata,BUFFERSIZE); bufferdata[result] = 0; POSITION pos = m_socketlist.GetHeadPosition(); //将数据发送给每个客户端 while (pos!=NULL) { CClientSocket* socket = (CClientSocket*)m_socketlist.GetNext(pos); if (socket != NULL) socket->Send(bufferdata,result); } }
|
客户端程序设计步骤如下。
ch1809实例位置:mr\18\sl\09
(1)创建一个基于对话框的工程,设置对话框资源如图18.17所示。
(2)在应用程序的InitInstance方法中初始化套接字。
//初始化套接字 WSADATA wsd; AfxSocketInit(&wsd);
|
(3)从CSocket类中派生一个子类CMysocket。在头文件中引用Afxsock.h头文件,目的是使用CSocket类;引用主对话框的头文件,并对主对话框进行前导声明,因为在CMysocket类中需要定义主对话框类指针。
(4)处理“发送”按钮的单击事件,发送数据到服务器。
图18.17 客户端窗口设计
void CClientDlg::OnButtonsend() { // TODO: Add your control notification handler code here CString str,temp; m_info.GetWindowText(str); if (str.IsEmpty()|m_name.IsEmpty()) return; temp.Format("%s说: %s",m_name,str); int num = pMysocket->Send(temp.GetBuffer(temp.GetLength()),temp.GetLength()); m_info.SetWindowText(""); m_info.SetFocus(); }
|
(5)在主对话框中定义一个CMysocket对象指针。添加ReceiveData成员方法,用于接收服务器传来的数据。
void CClientDlg::ReceiveData() { char buffer[200]; //接收传来的数据 int factdata = pMysocket->Receive(buffer,200);
buffer[factdata] = '\0'; CString str; str.Format("%s",buffer); int i = m_list.GetCount(); //将数据添加到列表框中 m_list.InsertString(m_list.GetCount(),str); }
|
(6)处理“连接”按钮的单击事件,连接服务器。
void CClientDlg::OnButtonjoin() { // TODO: Add your control notification handler code here UpdateData(true); CString servername = m_servername; //读取服务器名称 int port; port = 70; //获取端口
if (! pMysocket->Connect(servername,port)) //连接服务器 { MessageBox("连接服务器失败!"); return; } CString str; str.Format("%s----->%s",m_name,"进入聊天室"); int num = pMysocket->Send(str.GetBuffer(0),str.GetLength()); }
|
运行程序,效果如图18.18、图18.19、图18.20所示。
图18.18 服务器端窗口
图18.19 客户端窗口1
图18.20 客户端窗口2
【责任编辑:
阚书 TEL:(010)68476606】