Chinaunix首页 | 论坛 | 博客
  • 博客访问: 180756
  • 博文数量: 12
  • 博客积分: 3000
  • 博客等级: 中校
  • 技术积分: 240
  • 用 户 组: 普通用户
  • 注册时间: 2007-08-04 15:43
文章分类

全部博文(12)

文章存档

2011年(1)

2009年(1)

2008年(10)

我的朋友

分类: C/C++

2008-04-17 10:18:42

 服务器端必须能够完成三件事情:

(1)       服务器端聊天程序要在特定的端口上等待来自聊天客户的连接请求,并且需要维护一个客户连接,以记录所有成功的连接。

(2)       服务器端聊天程序要及时接收从各个聊天客户发送过来的信息,然后把这些信息转发到一个或多个客户连接。对于公共聊天室,服务器将把收到的信息向除源端外的所有客户发送过去。

(3)       服务器要监控这些连接的状态,在客户主动离开或发生故障时从列表中删除相应表项,并及时更新连接。

 

这些可以通过Visual C++MFC的封装类Csocket类提供相应功能实现。从Csocket派生出两个类CListenSocketCClientSocket,分别用来侦听客户和连接请求和建立与客户的连接。服务器只需要用一个侦听套接字ClistenSocket,然后根据客户的连接请求动态创建客户套接字CclientSockeMFCCptrList用来记录所有的客户套接字。

修改IDR_MAINFRAME的菜单设置如下:

   资源标识

       标题

    命令处理函数

ID_FILE_START

创建服务器

CMyQQServerDoc::OnFileStart()

 

主要函数实现如下:

void CMyQQServerDoc::OnFileStart()

{

      // TODO:创建服务器        

       CPortDlg m_Portdlg;  //一个对话框类的对象

      if(m_Portdlg.DoModal()!=IDOK)

           return;

//如已有一个侦听套接字,先把它关闭

   if (m_listenSocket!=NULL)

      {

           m_listenSocket->Close();

           delete m_listenSocket;

      }

      //创建一个新的侦听套接字

      m_listenSocket=new CListenSocket(this);

      //根据输入端口创建军服务器

      if(!m_listenSocket->Create(m_Portdlg.m_Port))

      {

           AfxMessageBox("创建SOCKET失败!");

           m_listenSocket=NULL;

           return;

      }

      //启动侦听套接字侦听连接

      if(!m_listenSocket->Listen())

      {

           AfxMessageBox("SOCKET 侦听失败!");

           delete m_listenSocket;

           m_listenSocket=NULL;

           return;

      }

      //删除列表中所有客户的套接字

      POSITION pos =m_list.GetHeadPosition();

      while (pos!=NULL)

      {

           CClientSocket * client =(CClientSocket*)m_list.GetNext(pos);

           delete client;

      }

      }

 

 

void CMyQQServerDoc::AcceptClient()

{

           //创建一个新的客户套接字

      m_clientSocket=new CClientSocket (this);

      if(!m_listenSocket->Accept (*m_clientSocket))

      {

           AfxMessageBox("SOCKET接收异常");

           delete m_clientSocket;

           m_clientSocket=NULL;

           return;

      }

 #ifdef _DEBUG

      AfxMessageBox("有用户加入!");

 #endif

      m_list.AddTail(m_clientSocket);

}

 

oid CMyQQServerDoc::ReadMessage(CClientSocket *socket)

{

           char buffer[MAX_BUFFER_SIZE];  //接收信息缓冲区

      //检查信息有效性

      int len=socket->Receive(buffer,MAX_BUFFER_SIZE-1);

      if(len<1)

      {

           AfxMessageBox("接收到空信息!");

           return;

      }

      buffer[len]=0;

      ShowMessage(socket,buffer);   //显示收到的信息

      SendMessage(socket,buffer);  //向其它客户套接字转发信息

}

 

void CMyQQServerDoc::ShowMessage(CClientSocket *socket, char *buffer)

{

           //获取对应的视图类

      POSITION pos=GetFirstViewPosition();

      while(pos!=NULL)

      {

           CMyQQServerView*eView= (CMyQQServerView*)GetNextView(pos);

           CEdit & edit=eView->GetEditCtrl();

           //获取客户对应的名称

           CString addr;

           UINT port;

           socket->GetPeerName(addr,port);

         char msg[MAX_BUFFER_SIZE];

           wsprintf(msg,"%d[%s]:%s\r\n",port,addr,buffer);  //格式化消息

           int len=eView->GetWindowTextLength ();

           edit.SetSel(len,len);

           edit.ReplaceSel(msg);

      }

}

 

void CMyQQServerDoc::SendMessage(CClientSocket *socket, char *buffer)

{

      POSITION pos=m_list.GetHeadPosition();

      while(pos!=NULL)

      {

        CClientSocket*client=(CClientSocket*)m_list.GetNext(pos);

        client->Send(buffer,strlen(buffer));

      }

}

 

 

阅读(1517) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:VC小型聊天程序设计之客户端

给主人留下些什么吧!~~