编程词典
明日图书
明日软件
用户注册
用户登录
站内
  当前位置:编程词典服务网 >> 编程词典社区论坛 >> 基于TCP协议的网络聊天室...
共有回复1条  每页10条  第1页/共1页  首页  上页  下页  尾页
1
  · 基于TCP协议的网络聊天室系统

用户:  大麦
发帖:  430 篇
作品:  0 个
回复:  108 篇
技术分:  1156 分
等级:  
注册:  2010-05-11 09:09:40



发表于:2010-07-13 15:27:36
          楼主

基于TCP协议的网络聊天室系统
利用这两个类设计一个网络聊天室系统。系统分为客户端和服务器端两个模块,下面分别介绍其实现过程。
1.客户端模块实现过程如下:
例如,使用CSocket类设计网络聊天室系统客户端
(1)创建一个基于对话框的工程,工程名称为“Client”。设计对话框资源如图1所示。
 
图1  客户端资源设计窗口
(2)在应用程序的InitInstance方法中初始化套接字。
WSADATA wsd;         //定义WSADATA对象
WSAStartup(MAKEWORD(2,2),&wsd);     //初始化套接字
(3)从CSocket类派生一个子类CClientSocket,在该类中添加m_pDialog成员。
CClientDlg *m_pDialog;        //添加成员变量
(4)在CClientSocket中添加SetDialog方法,用于设置成员变量。
void CClientSocket::SetDialog(CClientDlg *pDialog)
{
 m_pDialog = pDialog;       //设置成员变量
}
(5)改写CClientSocket类的OnReceive方法,在套接字有数据接收时调用该方法。
void CClientSocket::OnReceive(int nErrorCode)
{
 CSocket::OnReceive(nErrorCode);
 if (m_pDialog != NULL)       //判断成员变量是否为空
  m_pDialog->ReceiveText();     //调用对话框类的ReceiveText方法接收数据
}
(6)在对话框类中添加如下成员变量。
CClientSocket m_SockClient;       //定义套接字成员变量
CString  m_Name;         //定义一个字符串变量
(7)向对话框类中添加ReceiveText方法接收数据。
void CClientDlg::ReceiveText()
{
 char buffer[BUFFERSIZE];      //定义接收数据的缓冲区
 int len =  m_SockClient.Receive(buffer,BUFFERSIZE); //开始接收数据
 if (len != -1)         //判断是否接收到数据
 {
  buffer[len] = '';       //设置结束标记
  m_List.AddString(buffer);      //向列表中添加接收到的信息
 }
}
(8)在对话框初始化时创建套接字。
m_SockClient.Create();        //创建套接字
m_SockClient.SetDialog(this);       //设置套接字的成员变量
(9)处理登录按钮的单击事件,开始登录服务器。
void CClientDlg::OnLogin()
{
 CString strIP,strPort;        //定义两个字符串变量
 UINT port ;         //定义一个整数端口变量
 m_ServerIP.GetWindowText(strIP);     //获取服务器IP
 m_NickName.GetWindowText(m_Name);    //获取用户昵称
 m_ServerPort.GetWindowText(strPort);    //获取端口
 //判断服务器IP、端口号和用户昵称是否为空
 if (strIP.IsEmpty() || strPort.IsEmpty() || m_Name.IsEmpty())
 {
  MessageBox("请设置服务器信息","提示");   //显示提示对话框
  return;
 }
 port = atoi(strPort);        //将端口字符串传唤为整数
 if (m_SockClient.Connect(strIP,port))    //开始连接服务器
 {
  MessageBox("连接服务器成功!","提示");   //弹出提示信息
  CString str;        //定义字符串变量
  str.Format("%s----->%s",m_Name,"进入聊天室"); //设置输出信息
  m_SockClient.Send(str.GetBuffer(0),str.GetLength());//向服务器发送数据,再由服务器转发
 }
 else
 {
  MessageBox("连接服务器失败!","提示");   //显示提示对话框
 }
}
(10)处理“发送”按钮的单击事件,向服务器发送数据,再由服务器转发这些数据。
void CClientDlg::OnSendText()
{
 CString strText,strInfo;       //定义两个字符串变量
 m_Text.GetWindowText(strText);     //获取发送的内容
 if (!strText.IsEmpty() && !m_Name.IsEmpty())   //判断发送信息和昵称是否为空
 {
  strInfo.Format("%s说: %s",m_Name,strText);  //设置发送的文本
  //开始发送数据
  int len = m_SockClient.Send(strInfo.GetBuffer(strInfo.GetLength()),strInfo.GetLength());
 }
}
(11)运行程序,效果如图2、图3所示。
 
图2  客户端窗口1
 
图3  客户端窗口2
2.服务器端模块实现过程如下:
例如,使用CSocket类设计网络聊天室系统服务器端
(1)创建一个基于对话框的应用程序,工程名称为“Server”。设置对话框资源窗口如图4所示。
 
图4  服务器端设置窗口
(2)在应用程序的InitInstance方法中初始化套接字。
WSADATA wsd;         //定义WSADATA对象
AfxSocketInit(&wsd);         //初始化套接字
(3)从CSocket类派生一个子类CServerSocket,在该类中定义成员变量m_pDlg。
CServerDlg* m_pDlg;
(4)向CServerSocket类中添加SetDialog函数,为m_pDlg成员变量赋值。
void CServerSocket::SetDialog(CServerDlg* pDialog)
{
 m_pDlg = pDialog;        //为成员变量赋值
}
(5)改写CServerSocket类的OnAccept虚方法,在套接字中有连接请求时接收其连接。
void CServerSocket::OnAccept(int nErrorCode)
{
 CSocket::OnAccept(nErrorCode);
 if (m_pDlg)         //判断m_pDlg是否为空
  m_pDlg->AcceptConnect();     //调用主对话框的AcceptConnect方法
}
(6)从CSocket类再次派生一个新类CClientSocket,在该类中定义成员变量m_pDlg。
CServerDlg* m_pDlg;
(7)向CClientSocket类中添加SetDialog函数,为m_pDlg成员变量赋值。
void CClientSocket::SetDialog(CServerDlg* pDialog)
{
 m_pDlg = pDialog;        //为成员变量赋值
}
(8)改写CClientSocket类的OnReceive方法,在套接字有数据接收时接收数据。
void CClientSocket::OnReceive(int nErrorCode)
{
 CSocket::OnReceive(nErrorCode);
 if(m_pDlg)          //判断对话框是否为空
 {
  m_pDlg->ReceiveData(*this);     //调用对话框类的ReceiveData方法
 }
}
(9)在对话框类中添加如下成员变量。
CPtrList m_socketlist;        //定义套接字列表容器
CServerSocket m_ServerSock;       //定义套接字
(10)向对话框类中添加AcceptConnect方法,接收客户端的连接。
void CServerDlg::AcceptConnect()
{
 CClientSocket* psocket = new CClientSocket();   //创建一个套接字
 psocket->SetDialog(this);       //设置套接字的成员变量
 if (m_ServerSock.Accept(*psocket))     //接收套接字连接
  m_socketlist.AddTail(psocket);     //将套接字添加到列表容器中
 else
  delete psocket;        //连接失败,释放套接字
}
(11)向对话框类中添加ReceiveData方法,用于接收套接字数据。
void CServerDlg::ReceiveData(CSocket &socket)
{
 char bufferdata[BUFFERSIZE];      //定义数据缓冲区
 int len = socket.Receive(bufferdata,BUFFERSIZE);  //开始接收数据
 if (len != -1)         //判断是否接收到数据
 {
  bufferdata[len] = 0;       //设置数据结束标记
  POSITION pos = m_socketlist.GetHeadPosition(); //获取容器列表的首位置
  while (pos != NULL)       //遍历容器列表
  {
   //获取容器类表中的指定套接字
   CClientSocket* socket = (CClientSocket*)m_socketlist.GetNext(pos);
   if (socket != NULL)      //判断套接字是否为空
    socket->Send(bufferdata,len);   //向套接字发送数据
  }
 }
}
(12)处理“设置”按钮的单击事件,创建并开始监听套接字。
void CServerDlg::OnConfig()
{
 m_ServerSock.SetDialog(this);      //设置套接字成员变量
 CString strPort,strIP;        //定义两个字符串变量
 m_ServerPort.GetWindowText(strPort);    //获取端口字符串
 m_ServerIP.GetWindowText(strIP);     //获取服务器IP
 if (!strPort.IsEmpty() && !strIP.IsEmpty())    //判断端口和IP是否为空
 {
  UINT port = atoi(strPort);      //将端口转换为整数值
  m_ServerSock.Create(port,SOCK_STREAM,strIP); //创建套接字
  BOOL ret = m_ServerSock.Listen();    //将套接字置于监听模式
  if (ret)
   MessageBox("设置成功!","提示");   //弹出提示对话框
 }
}
(13)运行程序,效果如图5所示。
 
图5  服务器窗口

 

本帖赏分:0 分   回复数:1 篇     
修改   删除   引用   回复
  · reply

用户:  美若天成
发帖:  0 篇
作品:  0 个
回复:  3 篇
技术分:  36 分
等级:  学员
注册:  2010-11-10 17:07:06



回复于:2010-11-10 17:23:45
         1 楼
用mfc我就不是很习惯,这个东西我曾经直接用api做过。

我的成长过程的一些经历。。呵呵

修改   删除   引用
共有回复1条  每页10条  第1页/共1页  首页  上页  下页  尾页
1
吉林省明日科技有限公司提供技术支持. 
Copyright © 1999-2008 吉林省明日科技有限公司. 吉ICP备10002740
当前时区 GMT+8, 今天是 
刷新页面 - 关于我们 - 设为首页