本博文介绍了使用c++语言实现基于visual studio的聊天程序。
相关的project链接为
客户端:http://download.csdn.net/download/qq_28734159/10193551
服务器:http://download.csdn.net/download/qq_28734159/10193563
(服务器的下载请仔细看资源描述)
请使用visual studio2012及其以上的版本打开,否则可能发生错误。
相关分析:
1.课题目标和主要内容
课题目标:通过动手操作,可以从最初理解通信协议的抽象概念,逐步过渡到可以使用协议,按照协议编译程序实现所需功能,并进一步能够设计简单的协议
主要内容:在理解互联网协议和Socket的基础上,自行设计简单的应用层协议,设计并编程实现网络聊天软件。
开发平台:visual studio2012
主要工具:C++语言
2.系统的主要功能
功能 | 简要说明 |
生成一个简单的Windows窗口 | 建立win32程序 生成Windows窗口程序框架 |
客户端呼叫服务器并登陆 | 建立发送信息的通道,在此基础上可以互发信息 |
互发聊天信息 | 通过回车可以互相发送字符等简单的聊天内容 |
断开连接 | 断开通道,不能互发信息 |
改变字体颜色 | 改变显示在对话框里的字体颜色 |
自动回复 | 可以自动回复自己写下的内容 |
打开外部应用程序 | 可以打开QQ、百度等 |
清除历史记录 | 清除历史纪录框内的消息记录 |
快捷键退出 | 通过设置组合键Ctrl+D退出对话框 |
其他功能 | 在实验报告中有详叙 |
3.关键算法分析
(1) 实验必做功能,即基础功能是服务器和客户端之间能够进行简单的对话,包括发送简单的文字和其他简单的字符等。
1.发送信息
服务器端通过发送按钮下的函voidCChatServerDlg::OnBnClickedSend()来实现将写在编辑框中的字符发送到客户端(客户端通过发送按钮下的函数voidCChatClientDlg::OnBnClickedSend()),这个函数一方面将信息发送到对方,同时将信息添加到list控件即对话框中的历史记录框中,并完成对编辑框的刷新,使得编辑框能够重新输入新的字符。
2.接收信息
服务器端通过CServerSocket类中的:函数void OnAccept(int nErrorCode)将来自对方的信息翻译成相应的字符并写进历史记录对话框中(客户端实现相同的功能则是通过CMySocket类中的函数void OnReceive(intnErrorCode)实现相同的功能)
3.注意细节
要想完成对话框能够接发信息的功能,首先要将客户端和服务器端通过ip地址连接在一起,若在同一台电脑上实现此功能,则只需要将地址设置为本机地址127.0.0.1即可实现连接,同时要注意端口的匹配,否则不能实现正确的连接,当按下断开按钮之后,发送信息的通道断开,不能再发送信息。
(2) 附加功能,即在基础功能上添加的使得对话框功能更加强大的其他用处
功能一:同过按下回车键即可发送信息,相当于给发送按钮添加了回车这个快捷键
实现地方:客户端和服务器端
实现方法:鼠标右击回车按钮->属性改为true,然后回到对话框,ctrl+D对话框出现如下所示:
鼠标左击回车,回车数字变为1即可
功能二:组合键ctrl+X退出对话框
实现地方:服务器端
实现方法:重载函数BOOLCChatServerDlg::PreTranslateMessage(MSG*pMsg),通过判断虚拟键GetKeyState(VK_CONTROL) < 0是否被按下(小于0代表被按下),然后即可添加代码if(pMsg->wParam == 'X')来实现组合键的触发(此处和功能一的功能类似,但是实现方法大不相同)
功能三:改变字体颜色
实现地方:客户端和服务器端
(1) 客户端:逐行改变字体的颜色
实现方法:自定义一个派生自CListBox的类CColorListBox,添加函数int AddString(LPCTSTR lpszItem,COLORREF itemColor =RGB(255,0,0));这个函数实现的是将字符串以特定的颜色写进控件,例如m_list.AddString(temp1,RGB(a,b,c));就是将字符串temp1以abc三个数混合形成的颜色写进控件m_list.效果如下:
当然此处需要添加控件CComboBox cWordColor;里面写的是可以选择的颜色,效果如图所示
(2) 服务器端:以控件为单位,整体改变控件里面字体的颜色
实现方法:在类里面添加函数HBRUSHCChatServerDlg::OnCtlColor(CDC*pDC, CWnd*pWnd, UINTnCtlColor),并通过调用控件的id以if语句来判断是否在指定控件中写入字符,如if(IDC_LIST1==pWnd->GetDlgCtrlID())就是判断list控件即历史纪录框是否在使用,并以语句pDC->etTextColor(RGB(0,0,255)来给控件设置颜色,效果如下
与客户端不同,此处是通过按钮来改变选择字体颜色的。另外客户端和服务器端的编辑框都是通过这种方法来改变字体颜色的。
功能四:打开外部exe应用程序
实现地方:服务器端
实现方法:通过函数ShellExecute来调用外部应用程序,例如打开qq代码:ShellExecute(NULL,"open","C:\\ProgramFiles(x86)\\Tencent\\QQ\\QQProtect\\Bin\\QQProtect.exe",NULL,NULL,SW_SHOWNORMAL);注意此处的qq的路径中单斜杠写成双斜杠才是正确的
功能五:打开相应的网站
实现地方:服务器端
实现方法:和上述功能相似,也是用函数ShellExecute来实现的,不同的是在写应用程序路径的地方写成相应的网址即可,例如打开百度的代码为:ShellExecute(NULL,"open","http://www.baidu.com",NULL, NULL, SW_SHOWNORMAL);
功能六:实现自动回复的功能
实现地方:客户端
实现方法:在类CMySocket中添加语句
if(dlg->autosend==true)
{
dlg->m_autosend.GetWindowTextA(dlg->buff,200);
CString temp1="我:";
CString formatbuff="#c#s#"+(CString)"[自动回复]"+(CString)dlg->buff;
(*dlg->m_client).Send(formatbuff,200,0);
CString str;
dlg->m_tm=CTime::GetCurrentTime();
str=dlg->m_tm.Format("%X");
temp1=str+" "+temp1+"[自动回复]"+(CString)dlg->buff;
dlg->m_list.AddString(temp1);
dlg->m_list.UpdateData(FALSE);
}
其中autosend是按钮下的一个bool变量,以它来作为是否要实现自动回复的功能,此处自动回复的内容写在编辑框中,通过GetWindowTextA来获取并发送给对方,同时写进客户端的历史记录框中
效果如下:
功能七:清除历史记录
实现地方:客户端和服务器端
实现方法:在清除历史记录的按钮下,添加函数 m_list.ResetContent ();函数代表将m_list控件重置内容,相当于清除了历史记录,效果如下:
原状态:
按下清除历史记录的按钮后:
4.程序运行结果分析
服务器端:
客户端:
备注:
在使用时,先启动服务器,然后再启动客户端连接到服务器。
若在同一台电脑上同时启动服务器和客户端,则客户端里面的IP地址可以填写为本机的IP地址或者是127.0.0.1
若在不同的电脑上启动服务器和客户端,则客户端里面填写的IP只能是服务器电脑的IP地址。