基于UDP协议的网上聊天程序范例_第1页
基于UDP协议的网上聊天程序范例_第2页
基于UDP协议的网上聊天程序范例_第3页
基于UDP协议的网上聊天程序范例_第4页
基于UDP协议的网上聊天程序范例_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 湖南工业大学课 程 设 计资 料 袋 计算机与通信学院 学院(系、部) 2011 2012 学年第 1 学期 课程名称 计算机网络原理 指导教师 李建设 职称 副教授 学生姓名 蒋政 专业班级 软件092 学号 题 目 基于UDP协议网上聊天程序 成 绩 起止日期 2011 年 11 月 24 日 2011 年 12 月 4 日目 录 清 单序号材 料 名 称资料数量备 注1课程设计任务书2课程设计说明书3456课程设计任务书2010 2011学年第 2 学期学院(系、部) 计算机与通信学院 专业 软件工程 班级 091-3 课程名称: 计算机网络原理 学生姓名: 蒋政 设计题目: 基于UD

2、P协议网上聊天程序 指导教师: 李建设 完成期限:自 2011 年 11 月 24 日至 2011 年 12 月 4 日 共 2 周内容及任务一、设计内容实现一简单的聊天程序实现网上聊天,包括服务器和客户端。1. 支持多人聊天。2. 客户端具有图形化用户界面。二、设计任务课程设计说明书(纸质+电子版),内容包括:设计内容、系统分析(包括可行性分析、需求分析等)及功能分析;系统设计(要求画出系统整体功能框图、流程图、并给出相应地关键的代码且对所使用的主要数据结构进行说明等。)、设计总结(评价/遇到的问题/体会/建议等)、使用说明等。三、设计要求1. 按功能要求开发系统,能正确运行。程序代码书写规

3、范,有充足的注释。2. 课程设计所使用的编程语言任选,但建议使用C或C+;3. 绿色软件:程序运行不需安装,避免写系统和注册表;进度安排起止日期工作内容2011-11-242011-11-27选题2011-11-282011-11-29系统分析和设计;2011-11-302011-12-3熟悉软件开发工具、编码系统、系统测试2011-12-042011-12-05撰写并提交课程设计说明书 (含电子文档)、源程序等。主要参考资料1(美) Larry Peterson著,薛静锋等译. 计算机网络:系统方法 (第4版) ,机械工业出版社,20092(荷) Andrew S.Tanenbaum著,潘爱

4、民译. 计算机网络(第4版),清华大学出版社, 20043谢希仁著.计算机网络(第5版) ,电子工业出版社, 2008.14 吴功宜等著.计算机网络课程设计,机械工业出版社,2005指导教师(签字): 年 月 日系(教研室)主任(签字): 年 月 日课程设计说明书 课程名称: 计算机网络原理 设计题目: 基于UDP协议的聊天程序 专 业: 软件工程 班级: 092 学生姓名: 蒋政 学 号: 指导教师: 李建设 年 月 日 目录 1. 课程设计具体实现过程. 4 2. 具体代码的实现 8 3.注意事项. 124.参考文献. 12 一 . 多线程编程聊天程序的具体实现1 创建MFC-EXE 工程

5、,工程名为 Chat,Dialog based。2 删除对话框控件,添加自己的控件,各个控件的ID分别为:接受文本框的ID为IDC_EDIT_RECV,发送数据的文本框ID为IDC_EDIT_SEND,发送按钮的ID为IDC_BTN_SEND。其余默认即可。3 加载套接字库,进行版本协商MFC环境下使用 AfxSocketInit(查看MSDN帮助)AfxSocketInit加载的1.1版本,可以确保Socket库的释放MSDN中提到在 CWinApp:InitInstance中使用在这里就是 CChatAPP类的InitInstance中调用if(!AfxSocketInit()AfxMes

6、sageBox("加载套接字库失败!");return FALSE;4 刚才使用了 AfxSocketInit 需要加入头文件#include <Afxsock.h> 放入到 StdAfx.h的头文件中,StdAfx.h是预编译头文件,包括MFC工程必要的头文件5 在CChatDlg类中定义一个成员函数,作为套接字初始化工作 BOOL InitSocket()同时增加一个 变量 SOCKET m_socket6 实现 InitSocket()m_socket=socket(AF_INET,SOCK_DGRAM,0);if(INVALID_SOCKET=m_soc

7、ket)MessageBox("套接字创建失败!");return FALSE;SOCKADDR_IN addrSock;addrSock.sin_family=AF_INET;addrSock.sin_port=htons(1234);addrSock.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");int retval;retval=bind(m_socket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR);int retv = WSAGetLastError();if(SO

8、CKET_ERROR=retval)closesocket(m_socket);MessageBox("绑定失败!");return FALSE;return TRUE;7 在CChatDlg的OnInitDialog()的最后调用InitSocket()8 下面编写接收端程序(1)当接受数据时如果没有数据到来,recvfrom函数会阻塞,从而导致进程暂停运行,所以采用线程来完成 (2)创建线程后,我们需要传递两个参数,一个是套接字,一个是对话框的句柄(接受编辑框的句柄),这样可以通过套接字接受数据,传给接受编辑框,但CreateThread只能传递一个参数(第四个),但是

9、个指针9 在 CChatDlg的头文件中 定义一个结构体struct RECVPARAMSOCKET sock;HWND hwnd; /注意这里的分号10 在CChatDlg的OnInitDialog()最后,即InitSocket()后RECVPARAM *pRecvParam=new RECVPARAM;pRecvParam->sock=m_socket;pRecvParam->hwnd=m_hWnd;HANDLE hThread=CreateThread (NULL,0,RecvProc,(LPVOID)pRecvParam,0,NULL);CloseHandle(hThre

10、ad);return TRUE;11 加入线程函数,从MSDN中COPY加入一个全局函数,有的单位要求不允许使用全局函数,那这里加给 CChatDlg类,作为一个成员函数DWORD WINAPI RecvProc (LPVOID lpParameter)12此时程序报错,因为要执行 RecvProc 需要CChatDlg的实例,不能在类中调用,所以报错解决方法:在CChatDlg头文件中,将RecvProc函数定义为static类型13 实现线程函数SOCKET sock=(RECVPARAM*)lpParameter)->sock;HWND hwnd=(RECVPARAM*)lpPar

11、ameter)->hwnd;delete lpParameter;SOCKADDR_IN addrFrom;int len=sizeof(SOCKADDR);char recvBuf200;char tempBuf300;int retval;while(TRUE)retval=recvfrom(sock,recvBuf,200,0,(SOCKADDR*)&addrFrom,&len);if(SOCKET_ERROR=retval)break;sprintf(tempBuf,"%s说: %s",inet_ntoa(addrFrom.sin_addr),

12、recvBuf);:PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)tempBuf); /发送数据 传送一个自定义消息,传给窗口return 0;14 加入消息相应机制(1)在CChatDlg的头文件中 定义消息值,加入#defineWM_RECVDATAWM_USER+1(2)做一个消息相应函数原型的声明在CChatDlg的头文件的下方的 protected声明中加入afx_msg void OnRecvData(WPARAM wParam,LPARAM lParam); /注意加入了两个参数,因为PostMessage发送消息的过程中传递了参数(3)加入消息映

13、射:注意因为CAboutDlg类和CChatDlg类在一个CPP文件中,所以消息映射一定要加正确了找到 BEGIN_MESSAGE_MAP(CChatDlg, CDialog)在最后面写入: ON_MESSAGE(WM_RECVDATA,OnRecvData)第一个参数是 消息本身:WM_RECVDATA第二个参数是 消息相应函数:OnRecvData注意后面不要加分号(4)最后是消息相应函数的实现在 CPP最后加入void CChatDlg:OnRecvData(WPARAM wParam,LPARAM lParam)15实现刚才加入的 OnRecvData 消息相应函数CString st

14、r=(char*)lParam;CString strTemp;/获取旧文本GetDlgItemText(IDC_EDIT_RECV,strTemp); str+="rn" /增加一个换行str+=strTemp;SetDlgItemText(IDC_EDIT_RECV,str);/放到编辑框16双击发送按钮,系统自动生成按钮相应事件(1) 首先要获取IP,查看MSDN帮助CIPAddressCtrlCIPAddressCtrl对应的就是IP控件,通过一个DWORD类型的变量来接受IP地址首先得到控件的指针:GetDlgItem(IDC_IPADDRESS1)强制转换为 (

15、CIPAddressCtrl*)类型最后调用CIPAddressCtrl下的一个函数GetAddress完整的程序是DWORD dwIP;( (CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1) )->GetAddress(dwIP);(2) 得到IP地址后,可以发送数据,继续在后面加入代码SOCKADDR_IN addrTo;addrTo.sin_family=AF_INET;addrTo.sin_port=htons(1234);addrTo.sin_addr.S_un.S_addr=htonl(dwIP);CString strSend;GetDl

16、gItemText(IDC_EDIT_SEND,strSend);sendto(m_socket,strSend , strSend.GetLength()+1,0,(SOCKADDR*)&addrTo,sizeof(SOCKADDR);SetDlgItemText(IDC_EDIT_SEND,"");17 此时发现 文本框并没有 换行显示选择 接收数据的文本框控件,右键选择属性,在Styles中选择 Multiline就可以了;18 为了让我们回车就发送数据,可以设置发送按钮为缺省按钮,可以右键选择按钮属性,在在Styles中选择 Default button就可

17、以了。 二 . 具体代码的实现CPaintDC dc(this); / device context for paintingSendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);/ Center icon in client rectangleint cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cx

18、Icon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;/ Draw the icondc.DrawIcon(x, y, m_hIcon);elseCDialog:OnPaint();/ The system calls this to obtain the cursor to display while the user drags/ the minimized window.HCURSOR CChartDlg:OnQueryDragIcon()return (HCURSOR) m_hIcon;BOOL CChartDlg:InitSoc

19、ket()m_socket=socket(AF_INET,SOCK_DGRAM,0);if(INVALID_SOCKET=m_socket)MessageBox("套接字创建失败!");return FALSE;SOCKADDR_IN addrSock;addrSock.sin_family=AF_INET;addrSock.sin_port=htons(1234);addrSock.sin_addr.S_un.S_addr=inet_addr(GethostIP();int retval;retval=bind(m_socket,(SOCKADDR*)&addrS

20、ock,sizeof(SOCKADDR);int retv = WSAGetLastError();if(SOCKET_ERROR=retval)closesocket(m_socket);MessageBox("绑定失败!");return FALSE;return TRUE;DWORD WINAPI CChartDlg:RecvProc(LPVOID lpParameter)SOCKET sock=(RECVPARAM*)lpParameter)->sock;HWND hwnd=(RECVPARAM*)lpParameter)->hwnd;delete lp

21、Parameter;SOCKADDR_IN addrFrom;int len=sizeof(SOCKADDR);char recvBuf200;char tempBuf300;int retval;while(TRUE)retval=recvfrom(sock,recvBuf,200,0,(SOCKADDR*)&addrFrom,&len);if(SOCKET_ERROR=retval)break;sprintf(tempBuf,"%s说: %s",inet_ntoa(addrFrom.sin_addr),recvBuf);:PostMessage(hwnd

22、,WM_RECVDATA,0,(LPARAM)tempBuf); /发送数据 传送一个自定义消息,传给窗口return 0;void CChartDlg:OnRecvData(WPARAM wParam,LPARAM lParam)CString str=(char*)lParam;CString strTemp;/获取旧文本GetDlgItemText(IDC_EDIT_RECV,strTemp); if(strTemp!="")strTemp+="rn" /增加一个换行strTemp+=str;SetDlgItemText(IDC_EDIT_RECV

23、,strTemp);(CEdit*)GetDlgItem(IDC_EDIT_RECV)->LineScroll(CEdit*)GetDlgItem(IDC_EDIT_RECV)->GetLineCount();void CChartDlg:OnButtonSend() / TODO: Add your control notification handler code hereDWORD dwIP;( (CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1) )->GetAddress(dwIP);SOCKADDR_IN addrTo;addrT

24、o.sin_family=AF_INET;addrTo.sin_port=htons(1234);addrTo.sin_addr.S_un.S_addr=htonl(dwIP);CString strSend;GetDlgItemText(IDC_EDIT_SEND,strSend);sendto(m_socket,strSend , strSend.GetLength()+1,0,(SOCKADDR*)&addrTo,sizeof(SOCKADDR);SetDlgItemText(IDC_EDIT_SEND,"");CString strTemp;CString str="我说:"+strSend;/获取旧文本GetDlgItemText(IDC_EDIT_RECV,strTemp); if(strTemp!="")strTemp+="rn" /增加一个换行strTemp+=str;SetDlgItemText(IDC_EDIT_RECV,strTemp);(CEdit*)GetDlgItem(IDC_EDIT_RECV)->Line

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论