基于C++实现(WinForm) LAN 的即时通信软件【100010228】

您所在的位置:网站首页 winform刷新界面 基于C++实现(WinForm) LAN 的即时通信软件【100010228】

基于C++实现(WinForm) LAN 的即时通信软件【100010228】

2023-01-24 22:22| 来源: 网络整理| 查看: 265

基于 LAN 的即时通信软件的设计 一、概述 1.1 设计目的:

设计一个基于 LAN 的即时通信软件,实现在局域网下可靠的、稳定的即时通信功能以及其从属的附加功能。

1.2 设计内容: 1.2.1 功能设计:

·实现一对一的单播通信,包括消息发送与接收以及文件的发送与接收;

·实现一对一的单播通信,包括消息发送与接收以及文件的发送与接收;

·附加功能:实现登陆、注册、获取当前在线情况等功能;

1.2.2 界面设计:

·客户端的交互界面设计。

1.2.3 客户端、服务器设计:

·客户端需要完成的功能;

·服务器需要完成的功能;

·客户端、服务器的交互设计;

1.3 设计要求:

结合《计算机网络》课程所学的知识以及查阅相应的资料完成相应的设计内容,且需要保证设计的质量以及程序的可靠性和稳定性。

二、设计任务分析 2.1 功能设计分析:

·实现一对一的单播、多播通信:

主要运用消息转发技术,需要服务器来处理消息的解析和转发;其中消息的解析包括获取消息的发送者、接收者、类别;针对不同的解析结果需要做出不同的响应。

·实现附加功能:实现登陆、注册、获取当前在线情况等功能;将客户端对附加功能的调用当作特殊

的请求消息发送给服务器,服务器解析后做出不同的响应。

2.2 界面设计:

客户端界面需要有较好的交互性,因此需要设计:

·登陆、注册对话框:包括用户名输入框、登陆和注册按钮;

·主界面对话框:包括消息发送编辑框、消息接收显示区、好友在线情况显示区、发送按钮、以及登陆按钮;

2.3 客户端、服务器设计: 2.3.1 客户端设计:

·获取客户所发送的消息内容;

·根据客户要求封装消息并发送消息;

·接收服务器发来的消息;

·解析接收的消息并执行对应响应的功能;

2.3.2 服务器端设计:

·获取客户端发来的消息

·解析消息并执行对应的处理

·将处理结果封装成消息发送给指定客户

三、总体设计 3.1 界面设计结果 3.1.1 登陆、注册对话框

3.1.2 主界面对话框

说明:

编辑框 1:消息接收窗口编辑框 2:消息发送编辑框编辑框 3:消息接收者编辑框编辑框 4:当前在线用户显示框

“发送”按钮:发送编辑框 2 中的内容给编辑框 3 内对应的客户;

“文件”按钮:发送编辑框 2 中对应的文件给编辑框 3 内对应的客户;

“登陆”按钮:打开登陆、注册对话框;

3.2 客户端程序处理流程图:登陆、注册处理:

普通消息发送、文件发送、以及消息接受

3.3 服务器端程序处理流程图

四、程序实现 4.1 消息结构体: 4.1.1 消息结构体 structmes//消息结构体 { char from[32];//发送者 char to[32];//接收者 char content[MAX_PATH];//消息内容 }; 4.1.2 消息模板:

4.1.3 解释:

客户端和服务器会根据消息的三部分内容进行消息解析,不同的解析结果对应不同的消息处理。

4.2 客户端程序实现: 4.2.1 客户端自定义套接字类(继承 MFC 抽象类 CSOCKET)实现: class CMySocket : public CSocket { // Attributes public: CLanMessageDlg *dlg;//主对话框指针 // Operations public: CMySocket(); virtual ~CMySocket(); void OnReceive(int n);//消息接收响应 // Overrides public: // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMySocket) //}}AFX_VIRTUAL // Generated message map functions //{{AFX_MSG(CMySocket) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG // Implementation protected: }; void CMySocket::OnReceive(int n)//消息响应处理 { if(dlg->online)//在线才进行响应 { mes trans; if(!Receive((void*)&trans,sizeof(trans))){return;}//获取服务器消息 CString txt1=trans.from,txt2="在线用户"; if(txt1==txt2)//如果是"在线客户"消息 { CString show; show.Format("当前用户:%s\r\n%s:%s",dlg->me,trans.from,trans.content); dlg->m_online=show; dlg->UpdateData(false);//刷新主界面 } else if(trans.from[0]=='_')//如果是文件消息 { CStdioFile put; CString name=trans.from; name=name.Mid(1);//获取文件名 if(!put.Open(name,CFile::modeCreate|CFile::modeWrite))//将文件内容存储 { AfxMessageBox("创建文件失败!");return;} else put.WriteString(trans.content); put.Close(); } else {//如果是普通消息 CString show; show.Format("From %s:%s\r\n",trans.from,trans.content); dlg->m_show+=show; dlg->UpdateData(false);//刷新主界面 } } } 4.2.2 登陆、注册对话框实现: class CLanMessageDlg : public CDialog { // Construction public: CString me;//客户名字 CLanMessageDlg(CWnd* pParent = NULL); // standard constructor bool online;//是否在线 CSocket *client;//套接字指针 // Dialog Data //{{AFX_DATA(CLanMessageDlg) enum { IDD = IDD_LANMESSAGE_DIALOG }; CString m_online;//在线情况 CString m_to;//消息接收者 CString m_message;//要发送的消息 CString m_show;//接收到的消息 CString m_tips; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CLanMessageDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: HICON m_hIcon; // Generated message map functions //{{AFX_MSG(CLanMessageDlg) virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnButtonlogin(); afx_msg void OnButtonsend(); afx_msg void OnButtonfile(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; void CLOGINDLG::OnButtonlogin() //向服务端申请登陆 { // TODO: Add your control notification handler code here UpdateData(true);//刷新获取用户名 mes a; sprintf(a.from,"%s",m_name); sprintf(a.content,"登陆");//消息封装 //消息发送 if(!dlg->client->Send((void*)&a,sizeof(a))) {MessageBox("错误发送");return;} dlg->me=m_name; mes trans; //获取登陆结果 if(!dlg->client->Receive((void*)&trans,sizeof(trans))){return;} CString txt1="您已登陆成功!",txt2=trans.content; if(txt1==txt2) //如果登陆成功 { dlg->online=true; GetDlgItem(IDC_BUTTONLOGIN)->EnableWindow(false);//禁用登陆和注册按钮 GetDlgItem(IDC_BUTTONREGIST)->EnableWindow(false); } else { MessageBox(trans.content);//打印登陆失败原因 } } void CLOGINDLG::OnButtonregist()//向服务端申请注册 { // TODO: Add your control notification handler code here UpdateData(true);//获取注册用户名 mes a; sprintf(a.from,"%s",m_name); sprintf(a.content,"注册");//封装注册消息 //发送消息 if(!dlg->client->Send((void*)&a,sizeof(a))) {MessageBox("错误发送");return;} mes trans; //接收注册结果 if(!dlg->client->Receive((void*)&trans,sizeof(trans))){return;} CString txt1="注册成功!",txt2=trans.content; if(txt1==txt2) //如果注册成功 { MessageBox(trans.content); } } 4.2.3 主对话框实现: void CMySocket::OnReceive(int n)//消息响应处理 { if(dlg->online)//在线才进行响应 { mes trans; if(!Receive((void*)&trans,sizeof(trans))){return;}//获取服务器消息 CString txt1=trans.from,txt2="在线用户"; if(txt1==txt2)//如果是"在线客户"消息 { CString show; show.Format("当前用户:%s\r\n%s:%s",dlg->me,trans.from,trans.content); dlg->m_online=show; dlg->UpdateData(false);//刷新主界面 } else if(trans.from[0]=='_')//如果是文件消息 { CStdioFile put; CString name=trans.from; name=name.Mid(1);//获取文件名 if(!put.Open(name,CFile::modeCreate|CFile::modeWrite))//将文件内容存储 { AfxMessageBox("创建文件失败!");return;} else put.WriteString(trans.content); put.Close(); } else {//如果是普通消息 CString show; show.Format("From %s:%s\r\n",trans.from,trans.content); dlg->m_show+=show; dlg->UpdateData(false);//刷新主界面 } } } void CLanMessageDlg::OnButtonlogin() //登陆按钮实现 { // TODO: Add your control notification handler code here CLOGINDLG *dlg; dlg=new CLOGINDLG(); dlg->dlg=this; dlg->DoModal();//显示登陆、注册对话框 //登陆成功才可发送 if(online) { GetDlgItem(IDC_BUTTONSEND)->EnableWindow(true); GetDlgItem(IDC_BUTTONFILE)->EnableWindow(true); } } void CLanMessageDlg::OnButtonsend() //普通消息发送 { UpdateData(true); mes send; sprintf(send.from,"%s",me); sprintf(send.content,"%s",m_message); sprintf(send.to,"%s",m_to);//封装普通消息 if(!client->Send((void*)&send,sizeof(send))) {MessageBox("错误发送");return;} m_show+="To"+m_to+":"+m_message+"\r\n"; m_message=""; UpdateData(false);//刷新屏幕 // TODO: Add your control notification handler code here } void CLanMessageDlg::OnButtonfile() //发送文件 { // TODO: Add your control notification handler code here UpdateData(true); CStdioFile get; if(!get.Open(m_message,CFile::typeText,NULL)) {MessageBox("无效文件!");return;}//如果打开文件成功 CString txt,temp; while(get.ReadString(temp)) txt+=temp+"\r\n"; MessageBox(txt); mes send;//通知对方有文件传来 sprintf(send.from,"%s",me); sprintf(send.content,"发送文件"); sprintf(send.to,"%s",m_to); if(!client->Send((void*)&send,sizeof(send))) {MessageBox("错误发送");return;} sprintf(send.from,"_%s",get.GetFileName());//封装文件内容 sprintf(send.content,"%s",txt); sprintf(send.to,"%s",m_to); //将文件发送过去 if(!client->Send((void*)&send,sizeof(send))) {MessageBox("错误发送");return;} get.Close(); } 4.3 服务器程序实现: # include # include # include # include # include using namespace std; # pragma comment(lib, "ws2_32.lib") # define PORT 3000//服务器ip和端口号 # define IP_ADDRESS "127.0.0.1" struct mes//消息结构体 { char from[32];//发送者 char to[32];//接收者 char content[MAX_PATH];//内容 }; struct user//用户结构体 { string name;//用户名 SOCKET socket;//客户宿主套接字 bool online;//是否在线 }; string login="登陆",regist="注册"; static vector client;//客户动态数组 inline void updateonline()//更新在线人数 { string txt; for(int i=0;i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3