程序设计报告之简易聊天软件的设计与实现.docx

上传人:b****1 文档编号:10675201 上传时间:2023-05-27 格式:DOCX 页数:15 大小:190.79KB
下载 相关 举报
程序设计报告之简易聊天软件的设计与实现.docx_第1页
第1页 / 共15页
程序设计报告之简易聊天软件的设计与实现.docx_第2页
第2页 / 共15页
程序设计报告之简易聊天软件的设计与实现.docx_第3页
第3页 / 共15页
程序设计报告之简易聊天软件的设计与实现.docx_第4页
第4页 / 共15页
程序设计报告之简易聊天软件的设计与实现.docx_第5页
第5页 / 共15页
程序设计报告之简易聊天软件的设计与实现.docx_第6页
第6页 / 共15页
程序设计报告之简易聊天软件的设计与实现.docx_第7页
第7页 / 共15页
程序设计报告之简易聊天软件的设计与实现.docx_第8页
第8页 / 共15页
程序设计报告之简易聊天软件的设计与实现.docx_第9页
第9页 / 共15页
程序设计报告之简易聊天软件的设计与实现.docx_第10页
第10页 / 共15页
程序设计报告之简易聊天软件的设计与实现.docx_第11页
第11页 / 共15页
程序设计报告之简易聊天软件的设计与实现.docx_第12页
第12页 / 共15页
程序设计报告之简易聊天软件的设计与实现.docx_第13页
第13页 / 共15页
程序设计报告之简易聊天软件的设计与实现.docx_第14页
第14页 / 共15页
程序设计报告之简易聊天软件的设计与实现.docx_第15页
第15页 / 共15页
亲,该文档总共15页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

程序设计报告之简易聊天软件的设计与实现.docx

《程序设计报告之简易聊天软件的设计与实现.docx》由会员分享,可在线阅读,更多相关《程序设计报告之简易聊天软件的设计与实现.docx(15页珍藏版)》请在冰点文库上搜索。

程序设计报告之简易聊天软件的设计与实现.docx

程序设计报告之简易聊天软件的设计与实现

程序设计报告

(2012/2013学年第二学期)

 

题目:

简易聊天软件的设计与实现

 

专业

学生姓名

班级学号

指导教师

指导单位计算机学院计算机科学与技术系

日期2013年3月28日

评分细则

评分项

优秀

良好

中等

遵守机房规章制度

上机时的表现

学习态度

程序准备情况

程序设计能力

团队合作精神

课题功能实现情况

算法设计合理性

用户界面设计

报告书写认真程度

内容详实程度

文字表达熟练程度

回答问题准确度

简短评语

 

教师签名:

2013年3月29日

评分等级

备注

评分等级有五种:

优秀、良好、中等、及格、不及格

一、课题名称

简易聊天软件的设计与实现

二、课题内容和要求

1、课题内容:

本课程设计主要是设计并实现一个简单的聊天程序,创建基于多线程的聊天室程序。

2、课题要求:

要求能够实现基本的聊天功能,本聊天室允许两台计算机之间进行聊天,但是需要获取进行聊天的两台机之间IP地址,可以实现一对一的聊天。

三、原理分析

1、该程序实现局域网内的聊天功能,包括服务器端程序和客户端程序两部分。

客户端程序:

可连接到服务器,并将消息发送到服务器端和接受服务器端发送到的消息。

服务器端程序:

负责发送用户列表和转发客户端发送过来的消息。

本程序涉及到服务器端和客户端,采用同一个套接字。

2、该聊天软件是采用UDP连接,UDP是OSI参考模型中一种无连接的传输层协议,它提供了简单不可靠的信息传送服务。

由于UDP比较简单,UDP包含很少的字节,所以它在速度方面有很大优势。

很多常用的即时通软件,如QQ程序,都会使用UDP实现很多基本功能。

UDP是“面向非连接”的网络协议,它与“面向连接”的TCP协议对应。

在发送数据之前,并不与对方建立连接,而是直接把数据报发出去,不保证可靠的传输。

UDP相对TCP简单,在速度方面有很大优势,因为它的网络开销少,对传输可靠性要求不是很高的情况下,UDP的使用是网络程序的首选。

3、要实现聊天功能必须获取两台计算机的IP地。

在IP地址控件栏输入参与聊天对象的计算机的IP地址。

4、本程序的核心在于将消息的发送的和接收发在了两个不同的线程中,接收放在新创建的副进程中,因为其要一直处于响应状态,也就是需要一个while循环;发送放在主线程中。

这样消息的接收和发送就不存在先后顺序了,且一直处于循环中的接收也不会影响到发送。

5、程序代码中的新线程入口函数中可能没有必要传递两个参数进去,其中SOCKET参数可以在入口函数内部创建,SOCKET变量也就是声明是TCP还是UDP,和发送或接收没有必然的联系,如果这样的话,就没有必要声明“详细设计”第五步中的结构体了,CreateThread方法也刚好传递一个参数,即当前窗口的句柄。

四、需求分析

1、在VC++6.0中MFC中创建新文档,选中基本对话框栏,然后进行对话框的设置,选择不同的控件,分别设置接收数据、发送数据和发送的控件。

2、对需要用的变量进行定义并初始化等。

3、实现不同的功能响应不同的消息处理函数,实现套接字绑定获取IP地址等功能。

4、理解CWinApp中的InitInstance函数的用法及功能。

5、WSACleanup函数的调用与终止等。

6、各种不同代码的功能与实现原理。

五、概要设计

1、对需要用的变量进行定义或申明。

2、调用相应的MFC内置函数,对相应的变量进行初始化等操作。

3、程序设计的概要流程图如下:

 

 

 

 

图1程序设计流程图

六、详细设计

1、创建一个基于对话框的MFC程序设计,界面如下:

图2对话框界面

2、添加套接字库头文件:

函数能准确保证程序终止前调用WSACleanup的调用,该函数其实也是调用Win32中的WSAStartup,该函数的调用位置最好在CWinApp中的InitInstance中,包含头文件Afxsock.h,在StdAfx.h这个头文件中调用MFC的内置函数AfxSocketInit,该函数其他也是调用Win32中的WSASAtartup,该进行包含。

StdAfx.h头文件是一个预编译头文件,在该文件中包含了MFC程序运行的一些必要的头文件,如afxwin.h这样的MFC核心头文件等。

一些必要的头文件,如afxwin.h这样的MFC核心头文件等。

它是一个被程序加载的文件。

3、加载套接字库:

在CWinApp中的InitInstance添加如下代码:

if(FALSE==AfxSocketInit())

      {

           AfxMessageBox("套接字库加载失败!

");

           return FALSE;

}

4、创建套接字:

将自己假想成服务器端,进行套接字和地址结构的绑定,等待别人发送消息过来。

在CDialog中

添加成员变量:

SOCKETm_socket

添加自定义函数:

BOOLCChatDlg:

:

InitSocket()

{

   m_socket=socket(AF_INET,SOCK_DGRAM,0);//UDP连接方式

      if(INVALID_SOCKET==m_socket)

      {

           MessageBox("套接字创建失败!

");

           return FALSE;

      }

      SOCKADDR_INaddrServer; //将自己假想成server

      addrServer.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

      addrServer.sin_family=AF_INET;

      addrServer.sin_port=htons(1234);

      int retVal;

      retVal=bind(addrSock,(SOCKADDR*)&addrServer,sizeof(SOCKADDR));

      if(SOCKET_ERROR==retVal)

      {

           closesocket(addrSock);

           MessageBox("套接字绑定失败!

");

           return FALSE;

      }

      return TRUE;

}

5、在CChatDlg类的外部添加结构体:

struct RECVPARAM

{

    SOCKETsock;//保存最初创建的套接字

    HWNDhWnd;//保存对话框的窗口句柄

};

6、在对话框的初始化代码中完成线程的创建:

在CChatDlg:

:

OnInitDialog函数中添加下面的代码:

if(!

InitSocket())//服务器端的创建

      return FALSE;

      RECVPARAM*pRecvParam=newRECVPARAM;

      pRecvParam->hWnd=m_hWnd;

      pRecvParam->sock=m_socket;

 

说明:

1)接收部分应该一直处于响应状态,如果和发送部分放在同一段代码中,势必会阻塞掉发送功能的实现,所以考虑将接收放在单独的线程中,使它在一个while循环中,始终处于响应状态

2)因为需要传递两个参数进去,一个是recvfrom需要用的套接字,另一个是当收到数据后需要将数据显示在窗口中的对应文本框控件上,所以需要传递当前窗口的句柄,但CreateThread方法只能传递一个参数,即第四个参数,这时候就想到了采用结构体的方式传递。

HANDLEhThread=CreateThread(NULL,0,RecvProc,(LPVOID)pRecvParam,0,NULL);

CloseHandle(hThread);

 

7、创建线程入口函数RecvProc:

如果是成员函数的话,那它属于某个具体的对象,那么在调用它的时候势必要让程序创建一个对象,但该对象的构造函数有参数的话,系统就不知所措了,所以可以将函数创建为全局函数,即不属于类,但这失去了类的封装性,最好的方法是将该方法声明为静态方法,它不属于任何一个对象。

在CChatDlg类的头文件中添加:

static DWORDWINAPIRecvProc(LPVOIDlpParameter);

在cpp文件中添加:

DWORDWINAPICChatDlg:

:

RecvProc(LPVOIDlpParameter)

{

      RECVPARAM*pRecvParam=(RECVPARAM*)lpParameter;

      HWNDhWnd=pRecvParam->hWnd;

      SOCKETsock=pRecvParam->sock;

      char recvBuf[200];

      char resultBuf[200];

      SOCKADDR_INaddrFrom; //这个时候是假想成服务器端

      int len=sizeof(SOCKADDR_IN);

      while(TRUE)//处于持续响应状态

      {

         int retVal=recvfrom(sock,recvBuf,200,0,(SOCKADDR*)&addrFrom,&len); 

         if(SOCKET_ERROR==retVal)

         {

 AfxMessageBox("接收数据出错");

break;

         }

         else

         {

sprintf(resultBuf,"%ssaid:

%s",inet_ntoa(addFrom.sin_addr),recvBuf);//现在已经拿到客户端送过来的消息了,但因为自身是静态函数,所以拿不到当前窗口对象中的控件的句柄,也就不能对其赋值了,唯一办法就是用消息的形式将接收到的值抛出到窗口的消息队列中,等待消息处理

          :

:

PostMessage(hWnd,WM_RECVDATA,0,(LPARAM)resultBuf);        }

     }

      return 0;

}

8、自定义消息:

定义自定义消息的宏:

#defineWM_RECVDATAWM_USER+1

声明消息响应函数:

因为有参数要传递,所以wParam和lParam都要写,如果没有要传递,可以不写

afx_msg void OnRecvData(WPARAMwParam,LPARAMlParam);

消息映射:

ON_MESSAGE(WM_RECVDATA,OnRecvData)

定义消息响应函数:

void CChatDlg:

:

OnRecvData(WPARAMwParam,LPARAMlParam)

{

      CStringrecvData=(char*)lParam;

      CStringtemp; 

      GetDlgItemText(IDC_EDIT_RECV,temp);

      temp+="\r\n";

      temp+=recvData;

      SetDlgItemText(IDC_EDIT_RECV,temp);

}

自此,消息的接收和显示部分已经完成了

 

9、消息的发送:

在发送按钮点击的响应函数中添加:

    DWORDdword;

    CIPAddressCtrl*pIPAddr=(CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1);

    pIPAddr->GetAddress(dword); //因为对方有具体的IP地址值,我们假想对方是服务器端。

在发送的时候程序就从服务器的角色转变为客户端了

    SOCKADDR_INaddrServer;

    addrServer.sin_addr.S_un.S_addr=htonl(dword);

    addrServer.sin_family=AF_INET;

    addrServer.sin_port=htons(1234);

    CStringstrSend;

    GetDlgItemText(IDC_EDIT_SEND,strSend);

    sendto(m_socket,strSend,strlen(strSend)+1,0,(SOCKADDR*)&addrServer,sizeof(SOCKADDR));

SetDlgItemText(IDC_EDIT_SEND,"");

10、消息面版的控制:

至此,整个聊天软件的程序设计已经完成,但当你运行的时候发现两次发送的消息会在同一行出现。

如图所示:

此时,需要鼠标选中接收数据中的编辑一栏,更改其属性,选中属性中的样式然后选中多行。

整个聊天软件的是设计与实现已经完成。

七、测试数据及其结果分析

1、测试数据(如下图所示):

图3测试数据结果

2、结果分析

本聊天软件只可以在两台就计算机之间进行聊天,不可以再同一台上进行,并且程序设计时套接字已绑定,必须在获取了计算机的IP地址后才能进行聊天,必须在相同的条件下互相发送消息(比如同时联网或同是未连接网络)。

八、调试过程中的问题

1、由于未学过MFC等程序语言设计,在编程过程中遇到的很多代码都不认识,程序编写过程中比较麻烦。

2、在最初的情况下,就连最基本的对话框都不会建立,后来在图书馆借阅了各种书籍,解决了对话框的问题。

3、对话框问题解决后,仍是无从下手,在图书馆的借书里看见了一个完整的基于MFC的聊天软件设计,就想着按照上面一步步学习,但当做了几步后发现根本不可能,因为其中隐含的代码和知识完全不懂,后又在指导老师的帮助下懂了一些基本知识。

4、在以后的编写程序中,又遇到各种问题,在网上查了一些视频资料等最终把问题解决了。

最后在了完成后已经能运行了,可是运行了几次后又出现了问题,源代码中有一个if的选择语句,运行过程中总是选择返回值为false的那一条语句,在反复斟酌并在指导老师的帮助下最终解决了问题。

并实现了在两台计算机上进行聊天的功能。

九、程序设计总结

这次课程设计花了我不少时间,虽然可能存在不少瑕疵,但总的来说我成功的完成了,或许不是太完美,但是我辛辛苦苦动脑筋做的,是我完成的第一个实验设计,我很开心。

通过这次设计,我着实学到了点什么。

最基本的,我学会了以前不懂的对话框设计,学会了基本的MFC中界面设计。

还学会了每台电脑的IP地址的获取,并且对UDP和TCP两种不同方式有了一些了解,并对MFA、SOCKET等知识有的一些认识。

学会了简易聊天软件的实现和设计,完成了基本的聊天功能任务。

但是在设计过程中遇到了太多麻烦。

我不懂的和要学习的只是的确还有好多好多,在以后的学习中一定要好好学习程序语言设计。

通过这次实验,我发现原来我们平时经常用的聊天软件原来是这样开发的,这次试验让我对程序设计语言充满好奇,我要学习的还有好多好多。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2