友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
VC语言6.0程序设计从入门到精通-第62部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
第 11 章 网络编程
表 11…10 CChatServerDoc 类成员函数及其说明
成员函数 说明
void ProcessAccept() 当监听到客户端连接时调用此函数进行处理
void ProcessReceive(CClientSocket* pSocket) 当接收到信息时调用此函数,进行信息接收等操作
CMsg* ReadMsg(CClientSocket* pSocket) 接收信息
void SendMsg(CClientSocket* pSocket; CMsg* pMsg) 发送信息
void SendToAllClients(int nCode) 给各客户端发送消息
CMsg* AssembleMsg(CClientSocket* pSocket; int 封装消息,nCode 指定消息类型
nCode)
void SendForNewer(CMsg* pMsg) 给各客户端发送消息,告知有新用户加入
void UpdateMessageView(LPCTSTR lpszMessage) 更新服务器聊天信息视图
void UpdateChattersListView(CString sName ;
更新服务器用户列表视图
CClientSocket* pSocket)
BOOL IsUsedName(CString sNickName) 检查新登录的用户其用户名是否已被使用
void CloseSocket(CClientSocket* pSocket) 关闭连接
void DeleteChatter(CMsg* pMsg) 删除用户
virtual void DeleteContents() 当程序退出时做一些关闭、删除处理
下面为各函数编写代码。首先在构造函数中将各成员变量初始化,代码如下:
CChatServerDoc::CChatServerDoc()
{
// TODO: add one…time construction code here
m_pSocket = NULL;
m_msgList。RemoveAll();
m_connectionList。RemoveAll();
bIsNewChatter = TRUE;
m_ChattersList = 〃〃;
}
接着为“设定端口”菜单项添加响应函数,代码如下:
void CChatServerDoc::OnSetport()
{
// TODO: Add your mand handler code here
CPortDlg dlg;
if(dlg。DoModal() == IDOK)
{
//创建一个新的类进行监听
m_pSocket = new CListeningSocket(this);
if (m_pSocket…》Create(dlg。m_Port))
{
if (m_pSocket…》Listen())
return;
}
}
}
·301 ·
…………………………………………………………Page 313……………………………………………………………
Visual C++ 6。0 程序设计从入门到精通
为函数 ProcessAccept()添加如下代码:
void CChatServerDoc::ProcessAccept()
{
//创建一个新的 Socket 来处理与客户端的数据交互
CClientSocket* pSocket = new CClientSocket(this);
//如果接受客户端的连接请求
if (m_pSocket…》Accept(*pSocket))
{
//初始化
pSocket…》Init();
//将此连接 socket 加入连接链表中
m_connectionList。AddTail(pSocket);
}
//如果不接受连接
else
delete pSocket;
}
为函数 ProcessReceive()添加如下代码:
void CChatServerDoc::ProcessReceive(CClientSocket* pSocket)
{
CMsg* pMsg; //接收的消息
CString sName; //用户名
BOOL bIsUsedName = FALSE; //用户名是否已使用
bIsNewChatter = FALSE; //是否为新用户
do
{
//接收消息
pMsg = ReadMsg(pSocket);
//如果此消息是发送的新的用户名(在用户登录时客户端先发此消息)
if(pMsg…》code == SENDING_NICKNAME)
{
sName = pMsg…》m_strText;
bIsNewChatter = TRUE;
//检查此用户名是否已使用
if(IsUsedName(sName))
bIsUsedName = TRUE;
}
//如果连接已关闭则退出
if (pMsg…》m_bClose)
{
·302 ·
…………………………………………………………Page 314……………………………………………………………
第 11 章 网络编程
break;
}
}
while (!pSocket…》m_pArchiveIn…》IsBufferEmpty());
//如果是用户登录
if(bIsNewChatter)
{
//如果此用户名没有被使用
if(!bIsUsedName)
{
//发送消息通知各客户端
pMsg…》code = SENDING_CHATTERS_LIST;
m_ChattersList += sName + 〃:〃;
pMsg…》m_strText = m_ChattersList;
SendForNewer(pMsg);
}
//如果用户名已使用
else
{
//发消息通知此客户端
CMsg* msg = new CMsg;
msg…》Init();
msg…》code = USED_NAME;
CString string;
string。Format(〃用户名已被使用!〃);
msg…》m_strText = string;
SendMsg(pSocket; msg);
}
bIsNewChatter = FALSE;
bIsUsedName = FALSE;
}
//如果消息表明该客户端已关闭连接
if (pMsg…》m_bClose)
{
//发送消息通知各客户端
SendToAllClients(NORMAL_MESSAGE);
//在视图中将该用户删除
DeleteChatter(pMsg);
//关闭连接
·303 ·
…………………………………………………………Page 315……………………………………………………………
Visual C++ 6。0 程序设计从入门到精通
CloseSocket(pSocket);
//通知各客户端更新用户列表
SendToAllClients(SENDING_CHATTERS_LIST);
}
//如果是普通消息,发送给各客户端
else
SendToAllClients(NORMAL_MESSAGE);
}
为 ReadMsg() 函数编写如下代码:
CMsg* CChatServerDoc::ReadMsg(CClientSocket* pSocket)
{
static CMsg msg;
TRY
{
//接收数据
pSocket…》ReceiveMsg(&msg);
//如果是新用户登录则更新用户列表
if(msg。code == SENDING_NICKNAME)
{
UpdateChattersListView(msg。m_strText ; pSocket);
}
//如果是普通信息则更新聊天信息列表,并将信息加入到 m_msgList 链表中
if(msg。code == NORMAL_MESSAGE)
{
UpdateMessageView(msg。m_strText);
m_msgList。AddTail(msg。m_strText);
}
}
CATCH(CFileException; e)
{
CString strTemp;
strTemp。Format(〃无法读取数据!〃);
UpdateMessageView(strTemp);
msg。m_bClose = TRUE;
}
END_CATCH
return &msg;
}
为 SendMsg()函数编写如下代码:
void CChatServerDoc::SendMsg(CClientSocket* pSocket; CMsg* pMsg)
·304 ·
…………………………………………………………Page 316……………………………………………………………
第 11 章 网络编程
{
TRY
{
//调用 CClientSocket 的函数发送消息
pSocket…》SendMsg(pMsg);
}
CATCH(CFileException; e)
{
CString strTemp;
strTemp。Format(〃无法发送数据!〃);
UpdateMessageView(strTemp);
}
END_CATCH
}
为函数 IsUsedName()编写如下代码:
BOOL CChatServerDoc::IsUsedName(CString sNickName)
{
CString tempStr; tempList; sName;
tempStr = 〃〃;
tempList = m_ChattersList;
do
{
//利用“:”得到名字并查找(客户端发送的消息前面都有用户名加“:”)
sName = tempList。Left(tempList。Find(〃:〃; 0));
tempList = tempList。Mid(tempList。Find(〃:〃; 0) + 1);
//找到则返回真
if(sName == sNickName)
return TRUE;
}while(tempList。Find(〃:〃 ; 0) != …1);
//未被使用则返回假
return FALSE;
}
为函数 AssembleMsg()编写如下代码:
CMsg* CChatServerDoc::AssembleMsg(CClientSocket* pSocket ; int nCode)
{
static CMsg msg;
msg。Init();
for (POSITION pos1 = m_msgList。FindIndex(pSocket…》m_nMsgCount); pos1 != NULL;)
{
//信息内容
·305 ·
…………………………………………………………Page 317……………………………………………………………
Visual C++ 6。0 程序设计从入门到精通
msg。m_strText = m_msgList。GetNext(pos1);
//信息类型
msg。code = nCode;
}
pSocket…》m_nMsgCount = m_msgList。GetCount();
return &msg;
}
为函数 SendForNewer()编写如下代码:
void CChatServerDoc::SendForNewer(CMsg* pMsg)
{
for(POSITION pos = m_connectionList。GetHeadPosition(); pos != NULL;)
{
//对每个客户端都发送信息
CClientSocket* pSocket = (CClientSocket*)m_connectionList。GetNext(pos);
if (pSocket != NULL)
SendMsg(pSocket; pMsg);
}
}
为函数 SendToAllClients()编写如下代码:
void CChatServerDoc::SendToAllClients(int nCode)
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!