北邮程序设计实践--类qq聊天

程序设计实践

课题名称: 设 计 报 告

类qq聊天软件

课题概述

1.1课题目标和主要内容

采用vc6.0,c++语言利用Winsock函数编写聊天软件的服务器程序和客户端程序,

客户端可以和任意与它连接在同一服务器上的客户端交流。

1.2系统的主要功能

功能列表或功能框图,以及功能的简要说明。

服务器端功能:

1、 接受用户传送来的连接判断命令,并向用户发出响应命令。 2、 当有成员登陆,更新自身成员列表,并且同步更新客户端成员列表 3、 接受用户传送来的聊天信息,然后向链表中的用户转发。

客户端功能:

1、输入用户名,和服务器的连接。

2、接受来自服务器转发的消息及消息来源,并且进行显示。 3、点击在线成员图标会弹出发送消息窗口。 4、接受服务器消息,更新自身成员列表。

2. 系统设计

2.1 系统总体框架

应用Winsock,TCP/IP网络编程。

服务器端:

客户端:

2.2 系统详细设计

应用Winsock,TCP/IP网络编程。

CAboutDlg:自动生成的关于对话框的类,继承于CDialog类 CQQ_serverApp: CWinApp的共有继承类

client_info: 结构体,用来存储成员登陆情况,姓名,socket

CQQ_serverDlg: CDialog的共有继承类,包含服务器端的主要实现代码。 自定义消息格式:

“To:”:标识接受信息的客户端名称 “\r\n”表示结束 “From:”:标识发送此信息的客户端名称 “\r\n”表示结束

“List:”:服务器向客户端发送信息所包含的标识字段,不同客户端用“,”隔开,

“\r\n”表示结束

“Context:”:标识信息的主要内容 “\r\n.\r\n”表示结束

2.3 关键算法分析  服务器端:

算法1:CQQ_serverDlg::OnStartrun() //“开启服务器”的消息响应函数 {

//加载套接字库

WORD ver = MAKEWORD(2,0); //版本号2.0 WSADATA wsadata; …..

//创建基于TCP的套接字

socket_server = socket(AF_INET,SOCK_STREAM,NULL); //TCP/IP地址家族、流式套接字

….

//获取主机的ip地址 ……

//绑定端口号和ip

sockaddr_in addr; //sock地址结构体 addr.sin_family = AF_INET; //地址家族为TCP/IP addr.sin_port= htons(137); addr.sin_addr

= ip_addr;

//默认设置的端口号

“List:”:服务器向客户端发送信息所包含的标识字段,不同客户端用“,”隔开,

“\r\n”表示结束

“Context:”:标识信息的主要内容 “\r\n.\r\n”表示结束

2.3 关键算法分析

 服务器端:

算法1:CQQ_serverDlg::OnStartrun() //“开启服务器”的消息响应函数 {

//加载套接字库 WORD ver = MAKEWORD(2,0); //版本号2.0 WSADATA wsadata;

…..

//创建基于TCP的套接字 socket_server = socket(AF_INET,SOCK_STREAM,NULL);

//TCP/IP地址家族、流式套接字

….

//获取主机的ip地址 …… //绑定端口号和ip sockaddr_in addr; //sock地址结构体 addr.sin_family = AF_INET; //地址家族为TCP/IP addr.sin_port= htons(137); addr.sin_addr = ip_addr; //默认设置的端口号

if( bind(socket_server,(sockaddr *)&addr,sizeof(sockaddr)) ) { } //监听 listen(socket_server,5); //最大监听数为5 //设置异步套接字 ifAfxMessageBox("绑定端口号和ip出错"); return;

(SOCKET_ERROR==WSAAsyncSelect(socket_server,this->m_hWnd,WM_SOCKET,FD_ACCEPT | FD_CLOSE | FD_READ) )

{ } //提示信息 AfxMessageBox("服务器启动成功"); GetDlgItem(IDC_STARTRUN)->EnableWindow(false); //禁用“开启服务AfxMessageBox("异步套接字设置出错"); //提示消息 return; 器”按钮

}

********************************************************************* ********************************************************************* 算法2://向列表框控件中添加成员

创建LVITEM结构,赋予图像和名字,以及相应的索引,调用m_memlist.InsertItem()进行添加。

void CQQ_serverDlg::AddListMem(CString name,int index)

{

}

******************************************************************** ********************************************************************* 算法三:

//对接收到的数据依据标识字段进行筛选

(说明:根据自己的消息格式构造进行消息的筛选)

CString CQQ_serverDlg::getKeyMsg(CString recv_msg,CString keyword)

{

int index_start = 0,index_end = 0; //标识消息整体的开始与结束 int index = 0;

LVITEM lvitem; memset(&lvitem,0,sizeof(LVITEM)); lvitem.mask = LVIF_IMAGE | LVIF_TEXT; lvitem.iItem = index; lvitem.pszText = name.GetBuffer(0); lvitem.iImage = index; m_memlist.InsertItem(&lvitem);

CString str_temp = ""; //存储消息主要内容:成员名 if("To" == keyword) { index_start = recv_msg.Find("To:"); index_end = recv_msg.Find("\r\n",index_start);

for(index = index_start+3;index

}

if("From" == keyword)

。。。。。。。。

} { } return str_temp; str_temp += recv_msg.GetAt(index);

******************************************************************** ********************************************************************* 算法四:

//向所有列表成员发送成员名信息,更新成员名列表

void CQQ_serverDlg::SendAllMem()

{

CString name_list = ""; int count = m_memlist.GetItemCount(); //获取在线成员数目

} for(int i=0;i

 客户端:

客户端与服务器端在编写上有很多相似之处,相似函数处理这里不再做赘述。 算法一:

//双击成员是调用的响应函数,显示对话框

void CQQ_clientDlg::OnDblclkListmem(NMHDR* pNMHDR, LRESULT* pResult)

{

//获取用户双击选择的成员的位置

POSITION pos = m_listmem.GetFirstSelectedItemPosition(); if (pos == NULL) { } else { AfxMessageBox("No items were selected!\n"); //提示消息 return;

//获取列表成员的索引

int nItem = m_listmem.GetNextSelectedItem(pos);

//获取制定索引的成员名

to_name = m_listmem.GetItemText(nItem,0);

//显示发送信息对话框

} *pResult = 0; } m_dlg.DoModal();

2.4 其他

CAboutDlg:自动生成的关于对话框的类,继承于CDialog类

CQQ_serverApp: CWinApp的共有继承类

CQQ_serverDlg: CDialog的共有继承类,包含服务器端的主要实现代码

继承程序框架本身就有的类,极大辅助了程序的编写。

3. 程序运行结果分析

运行效果图:

第10页

第11页

连接错误时:

4. 总结

4.1课题的难点和关键点

1、对于socket网络编程需要学习理解,尤其需要从最基础的开始学习。

本程序中应用了winsock进行编写,需要对如send(),recv(),等函数了解,尤其要掌握其参数类型,这样才能在应用使得心应手。比如在这次编程中因为参数类型的原因出了好几个错误。

第12页

2.程序涉及到成员名及消息的处理,所以需要自定义消息格式才能解决,尽管处理起来非常简单,但是在自己想出思路前还是用了一些时间。

3.调试上因为有了第一次实验的基础,这一次相对要好得多,对于常规处理还是能够解决,但是有时还是会出现不知所措的情况。

4.2 本课题的评价

通过本次试验,基本掌握了MFC编程的知识及WinSock的基本知识,对于Winsock函数有了较好地掌握,能够熟练使用,并且对于窗口化程序中各种函数的调用、响应原理也有很好的理解。

不足:界面上需要更加美化、同时也可以增加消息记录、文件传输等功能。

4.3心得体会

这次编程可以说是第一次编写大程序,也认识到真正实践时是各种知识的综合使用,要求知识面更为全面。而且也学习了winsock编程的知识,对消息响应原理有了更进一步的理解。

同时相应的也是花费时间最多的程序,一方面是程序本身较之前要复杂一些,另一方面是需要学习新的知识。期间遇到很多问题但最终通过努力,通过查资料、上网解决了,还是挺高兴的。

但是也不得不看到程序还有很多需要完善的地方,编写的较为简陋,界面上需要更加美化、同时也可以增加消息记录、文件传输等功能,而这方面我将会在日后加以完善。

5. 参考文献

[1] 罗莉琴 詹祖桥 《Windows 网络编程》 人民邮电出版社 2011版

[2] 孙浩 《Visual C++ 范例大全》 机械工业出版社 2009版

第13页

程序设计实践

课题名称: 设 计 报 告

类qq聊天软件

课题概述

1.1课题目标和主要内容

采用vc6.0,c++语言利用Winsock函数编写聊天软件的服务器程序和客户端程序,

客户端可以和任意与它连接在同一服务器上的客户端交流。

1.2系统的主要功能

功能列表或功能框图,以及功能的简要说明。

服务器端功能:

1、 接受用户传送来的连接判断命令,并向用户发出响应命令。 2、 当有成员登陆,更新自身成员列表,并且同步更新客户端成员列表 3、 接受用户传送来的聊天信息,然后向链表中的用户转发。

客户端功能:

1、输入用户名,和服务器的连接。

2、接受来自服务器转发的消息及消息来源,并且进行显示。 3、点击在线成员图标会弹出发送消息窗口。 4、接受服务器消息,更新自身成员列表。

2. 系统设计

2.1 系统总体框架

应用Winsock,TCP/IP网络编程。

服务器端:

客户端:

2.2 系统详细设计

应用Winsock,TCP/IP网络编程。

CAboutDlg:自动生成的关于对话框的类,继承于CDialog类 CQQ_serverApp: CWinApp的共有继承类

client_info: 结构体,用来存储成员登陆情况,姓名,socket

CQQ_serverDlg: CDialog的共有继承类,包含服务器端的主要实现代码。 自定义消息格式:

“To:”:标识接受信息的客户端名称 “\r\n”表示结束 “From:”:标识发送此信息的客户端名称 “\r\n”表示结束

“List:”:服务器向客户端发送信息所包含的标识字段,不同客户端用“,”隔开,

“\r\n”表示结束

“Context:”:标识信息的主要内容 “\r\n.\r\n”表示结束

2.3 关键算法分析  服务器端:

算法1:CQQ_serverDlg::OnStartrun() //“开启服务器”的消息响应函数 {

//加载套接字库

WORD ver = MAKEWORD(2,0); //版本号2.0 WSADATA wsadata; …..

//创建基于TCP的套接字

socket_server = socket(AF_INET,SOCK_STREAM,NULL); //TCP/IP地址家族、流式套接字

….

//获取主机的ip地址 ……

//绑定端口号和ip

sockaddr_in addr; //sock地址结构体 addr.sin_family = AF_INET; //地址家族为TCP/IP addr.sin_port= htons(137); addr.sin_addr

= ip_addr;

//默认设置的端口号

“List:”:服务器向客户端发送信息所包含的标识字段,不同客户端用“,”隔开,

“\r\n”表示结束

“Context:”:标识信息的主要内容 “\r\n.\r\n”表示结束

2.3 关键算法分析

 服务器端:

算法1:CQQ_serverDlg::OnStartrun() //“开启服务器”的消息响应函数 {

//加载套接字库 WORD ver = MAKEWORD(2,0); //版本号2.0 WSADATA wsadata;

…..

//创建基于TCP的套接字 socket_server = socket(AF_INET,SOCK_STREAM,NULL);

//TCP/IP地址家族、流式套接字

….

//获取主机的ip地址 …… //绑定端口号和ip sockaddr_in addr; //sock地址结构体 addr.sin_family = AF_INET; //地址家族为TCP/IP addr.sin_port= htons(137); addr.sin_addr = ip_addr; //默认设置的端口号

if( bind(socket_server,(sockaddr *)&addr,sizeof(sockaddr)) ) { } //监听 listen(socket_server,5); //最大监听数为5 //设置异步套接字 ifAfxMessageBox("绑定端口号和ip出错"); return;

(SOCKET_ERROR==WSAAsyncSelect(socket_server,this->m_hWnd,WM_SOCKET,FD_ACCEPT | FD_CLOSE | FD_READ) )

{ } //提示信息 AfxMessageBox("服务器启动成功"); GetDlgItem(IDC_STARTRUN)->EnableWindow(false); //禁用“开启服务AfxMessageBox("异步套接字设置出错"); //提示消息 return; 器”按钮

}

********************************************************************* ********************************************************************* 算法2://向列表框控件中添加成员

创建LVITEM结构,赋予图像和名字,以及相应的索引,调用m_memlist.InsertItem()进行添加。

void CQQ_serverDlg::AddListMem(CString name,int index)

{

}

******************************************************************** ********************************************************************* 算法三:

//对接收到的数据依据标识字段进行筛选

(说明:根据自己的消息格式构造进行消息的筛选)

CString CQQ_serverDlg::getKeyMsg(CString recv_msg,CString keyword)

{

int index_start = 0,index_end = 0; //标识消息整体的开始与结束 int index = 0;

LVITEM lvitem; memset(&lvitem,0,sizeof(LVITEM)); lvitem.mask = LVIF_IMAGE | LVIF_TEXT; lvitem.iItem = index; lvitem.pszText = name.GetBuffer(0); lvitem.iImage = index; m_memlist.InsertItem(&lvitem);

CString str_temp = ""; //存储消息主要内容:成员名 if("To" == keyword) { index_start = recv_msg.Find("To:"); index_end = recv_msg.Find("\r\n",index_start);

for(index = index_start+3;index

}

if("From" == keyword)

。。。。。。。。

} { } return str_temp; str_temp += recv_msg.GetAt(index);

******************************************************************** ********************************************************************* 算法四:

//向所有列表成员发送成员名信息,更新成员名列表

void CQQ_serverDlg::SendAllMem()

{

CString name_list = ""; int count = m_memlist.GetItemCount(); //获取在线成员数目

} for(int i=0;i

 客户端:

客户端与服务器端在编写上有很多相似之处,相似函数处理这里不再做赘述。 算法一:

//双击成员是调用的响应函数,显示对话框

void CQQ_clientDlg::OnDblclkListmem(NMHDR* pNMHDR, LRESULT* pResult)

{

//获取用户双击选择的成员的位置

POSITION pos = m_listmem.GetFirstSelectedItemPosition(); if (pos == NULL) { } else { AfxMessageBox("No items were selected!\n"); //提示消息 return;

//获取列表成员的索引

int nItem = m_listmem.GetNextSelectedItem(pos);

//获取制定索引的成员名

to_name = m_listmem.GetItemText(nItem,0);

//显示发送信息对话框

} *pResult = 0; } m_dlg.DoModal();

2.4 其他

CAboutDlg:自动生成的关于对话框的类,继承于CDialog类

CQQ_serverApp: CWinApp的共有继承类

CQQ_serverDlg: CDialog的共有继承类,包含服务器端的主要实现代码

继承程序框架本身就有的类,极大辅助了程序的编写。

3. 程序运行结果分析

运行效果图:

第10页

第11页

连接错误时:

4. 总结

4.1课题的难点和关键点

1、对于socket网络编程需要学习理解,尤其需要从最基础的开始学习。

本程序中应用了winsock进行编写,需要对如send(),recv(),等函数了解,尤其要掌握其参数类型,这样才能在应用使得心应手。比如在这次编程中因为参数类型的原因出了好几个错误。

第12页

2.程序涉及到成员名及消息的处理,所以需要自定义消息格式才能解决,尽管处理起来非常简单,但是在自己想出思路前还是用了一些时间。

3.调试上因为有了第一次实验的基础,这一次相对要好得多,对于常规处理还是能够解决,但是有时还是会出现不知所措的情况。

4.2 本课题的评价

通过本次试验,基本掌握了MFC编程的知识及WinSock的基本知识,对于Winsock函数有了较好地掌握,能够熟练使用,并且对于窗口化程序中各种函数的调用、响应原理也有很好的理解。

不足:界面上需要更加美化、同时也可以增加消息记录、文件传输等功能。

4.3心得体会

这次编程可以说是第一次编写大程序,也认识到真正实践时是各种知识的综合使用,要求知识面更为全面。而且也学习了winsock编程的知识,对消息响应原理有了更进一步的理解。

同时相应的也是花费时间最多的程序,一方面是程序本身较之前要复杂一些,另一方面是需要学习新的知识。期间遇到很多问题但最终通过努力,通过查资料、上网解决了,还是挺高兴的。

但是也不得不看到程序还有很多需要完善的地方,编写的较为简陋,界面上需要更加美化、同时也可以增加消息记录、文件传输等功能,而这方面我将会在日后加以完善。

5. 参考文献

[1] 罗莉琴 詹祖桥 《Windows 网络编程》 人民邮电出版社 2011版

[2] 孙浩 《Visual C++ 范例大全》 机械工业出版社 2009版

第13页


相关文章

  • 成都找工作总结
  • 楼主是一名北邮土著,09级本13级硕,准备明年毕业后回成都工作,于是建了一个我们这一届的回成都找工作群,机缘巧合认识了上一届回成都找工作群的群主(Richargo 学长).学长希望把回成都找工作的北邮人写面经分享互助的传统继续下去,于是费心 ...查看


  • 进入大学生活
  • 进入大学生活,你们准备好了吗? 方滨兴(2012年8月29日) 各位同学,各位老师,大家上午好: 首先,我要感谢你们在场的近三千四百名新生,感谢你们选择了北邮!其次,我要祝贺你们,祝贺你们如愿以偿地步入了一个崭新的境界,踏入到了一个全新的空 ...查看


  • 市场营销社会实践
  • 市场营销社会实践报告 北邮网络学校 学生:蔡小蕊 在现代化社会,是一个竞争非常激烈的社会,强者胜劣者淘汰的社会,如果拥有一份稳定的工作对每个人来说是梦寐以求的事情! 中国加入了世贸组织后外经济日趋变化,有新的机会也有了更多的挑战,中国的经济 ...查看


  • 21北邮电子科学与技术导论论文
  • 浅谈光信息科学与技术的发展 何佳羲 电子工程(7)班 2012211009 21世纪,随着现代科学技术的飞速发展,人类历史即将进入一个崭新的时代──信息时代.其鲜明的时代特征是,支撑这个时代的诸如能源.交通.材料和信息等基础产业均将得到高度 ...查看


  • 技术类求职经验
  • 前言: 前些日子看了Steve兄的求职分享帖,写的很好,相信对于将来想从事非技术类的师弟师妹们,一定有很大的积极作用. 相信我们09级的同学们很多人还记得07级信通院求职交流会中大脑门师兄的求职分享,我的自我介绍就是完全以大脑门师兄的模板为 ...查看


  • 北邮13秋人力资源管理期末考试(含答案)
  •  13秋期末考试范围 注意:本范围与期末考试内容相似度超过80%:但是由于是开卷考试,且无计算等学生没有把握的题目,故不提供答案,只提供答题方法. 一.填空题(每小题2分) 1.当今社会的基本资源种类有 人 才 物 信息 时间 2.古典管 ...查看


  • 北邮[市场调查与预测]第一次阶段作业
  • 北邮<市场调查与预测>第一次阶段作业 一.判断题(共10道小题,共100.0分) 1. 市场直接资料是由预测者自己组织市场调查取得的,因此适用性强.可信 程度高.但其取得需要较多的费用. A. 正确 B. 错误 2. 市场重点调 ...查看


  • 京东技术进校园活动策划
  • 京东技术高校行之北京邮电大学站 活动策划 一.活动概况 ● 活动名称:投资人眼中的创业圈--交流 ● 活动举办单位:北邮创新与创业协会,京东研发部, ● 活动意义:京东技术高校行是由京东研发部联合多所计算机专业院校主办,是一个面向 全国计算 ...查看


  • 2015年北邮管理学基础第一阶段作业
  • 2015年北邮管理基础学第一阶段作业 一.判断题(共10道小题,共50.0分) 1. 在企业面临外部机遇并且明显处于劣势的时候,企业应选择的战略方案是扭转型战 略. A. 正确 B. 错误 知识点: 第一次阶段作业 学生答[A;] 案: 得 ...查看


热门内容