WinSocket高级实现(聊天室的实现)(二)

发表于:2007-07-01来源:作者:点击数: 标签:
上回我带领大家制作了一个聊天室的客户端,今天我来讲解一下这个聊天室的 服务器 端怎样编写。 首先我们和上回一样,仍然建立一个MFC的程序,取名为ChatRoomServer,注意一定不要忘记在Step 2时钩上Windows Sockets。我们这个服务端的程序很简单。你只需要在


上回我带领大家制作了一个聊天室的客户端,今天我来讲解一下这个聊天室的服务器端怎样编写。

首先我们和上回一样,仍然建立一个MFC的程序,取名为ChatRoomServer,注意一定不要忘记在Step 2时钩上Windows Sockets。我们这个服务端的程序很简单。你只需要在他默认建立的对话框上增加两个按钮就行了。如下图:

其中Start、Stop是启动和中止服务的,是不是很简单。

其中值得注意的是,我们需要用Class Wizard为这两个按钮各增加一个控制变量:m_IDC_BUTTON_START、m_IDC_BUTTON_STOP。还有是为这两个按钮增加上对应的函数:CChatRoomServerDlg::OnButtonStart() 、CChatRoomServerDlg::OnButtonStop()。其具体内容如下:

void CChatRoomServerDlg::OnButtonStart()
{
  // TODO: Add your control notification handler code here
  m_IDC_BUTTON_START.EnableWindow(FALSE);
  ListenSocket.Create(6767);
  ListenSocket.Listen();
  m_IDC_BUTTON_STOP.EnableWindow(TRUE);
}

void CChatRoomServerDlg::OnButtonStop()
{
  // TODO: Add your control notification handler code here
  m_IDC_BUTTON_STOP.EnableWindow(FALSE);
  ListenSocket.Close();
  m_IDC_BUTTON_START.EnableWindow(TRUE);
}

其中ListenSocket是由CListenSocket定义的成员变量。其具体内容如下:

class CListenSocket : public CSocket
{
  // Attributes
  public:

  // Operations
  public:
  CClientSocketList CCSL;
  CListenSocket();
  virtual ~CListenSocket();

  // Overrides
  public:
  // ClassWizard generated virtual function overrides
  //{{AFX_VIRTUAL(CListenSocket)
  public:
  virtual void OnAclearcase/" target="_blank" >ccept(int nErrorCode);
  //}}AFX_VIRTUAL

  // Generated message map functions
  //{{AFX_MSG(CListenSocket)
  // NOTE - the ClassWizard will add and remove member functions here.
  //}}AFX_MSG

  // Implementation
  protected:
};

void CListenSocket::OnAccept(int nErrorCode)
{
  // TODO: Add your specialized code here and/or call the base class
  CClientSocket *tmp=new CClientSocket(&CCSL);
  Accept(*tmp);
  CCSL.Add(tmp);
  CSocket::OnAccept(nErrorCode);
}

还有一个为生成客户Sockets队列的类:CClientSocketList

class CClientSocketList
{
  public:
  BOOL Sends(CClientSocket *);
  BOOL Add(CClientSocket *);
  CClientSocket * Head;
  CClientSocketList();
  virtual ~CClientSocketList();
};

BOOL CClientSocketList::Add(CClientSocket *add)
{
  CClientSocket *tmp=Head;
  if (!Head)
  {
    Head=add;
    return true;
  }
  while (tmp->Next) tmp=tmp->Next;
  tmp->Next=add;
  return true;
}

BOOL CClientSocketList::Sends(CClientSocket *tmp)
{
  char buff[1000];
  int n;
  CClientSocket *curr=Head;
  n=tmp->Receive(buff,1000);
  buff[n]=0;
  while (curr)
  {
    curr->Send(buff,n);
    curr=curr->Next;
  }
  return true;
}
 

其中的成员函数:CClientSocket * Head用的是由CSocket直接派生出来的。CClientSocket定义如下:

class CClientSocket : public CSocket
{
  // Attributes
  public:
  // Operations
  public:
  CClientSocket(CClientSocketList *);
  virtual ~CClientSocket();
  // Overrides
  public:
  CClientSocketList *List;
  CClientSocket * Front;
  CClientSocket * Next;
  // ClassWizard generated virtual function overrides
  //{{AFX_VIRTUAL(CClientSocket)
  public:
  virtual void OnReceive(int nErrorCode);
  virtual void OnClose(int nErrorCode);
  //}}AFX_VIRTUAL
  // Generated message map functions
  //{{AFX_MSG(CClientSocket)
  // NOTE - the ClassWizard will add and remove member functions here.
  //}}AFX_MSG
  // Implementation
  protected:
};

void CClientSocket::OnReceive(int nErrorCode)
{
  // TODO: Add your specialized code here and/or call the base class
  List->Sends(this);
  CSocket::OnReceive(nErrorCode);
}
 

这样我们的聊天室就做好了,怎么样是不是很简单。(大家如果想在本机试验的话,可以将服务器地址填写为:127.0.0.1,这样可以使自己既当客户端,又做服务端。)我想这个小程序可以使你向网络编程跨近了一步。在此我提供源代码,供大家参考。有什么问题也可以给我来信,大家互相交流。


原文转自:http://www.ltesting.net