ImageVerifierCode 换一换
格式:DOCX , 页数:16 ,大小:35.69KB ,
资源ID:30758921      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/30758921.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(基于UDP协议的网上聊天程序.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

基于UDP协议的网上聊天程序.docx

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

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

3、1. 按功能要求开发系统,能正确运行。程序代码书写规范,有充足的注释。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版) ,机械工业出版社,2009

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

5、参考文献. 12 一 . 多线程编程聊天程序的具体实现1 创建MFC-EXE 工程,工程名为 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类

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

7、ALID_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(127.0.0.1); int retval; retval=bind(m_socket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR); int retv = WSAGetLastError(); if(SOCK

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

9、atDlg的头文件中 定义一个结构体struct RECVPARAM SOCKET 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(hThread); return

10、 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*)lpParameter)-hwnd

11、; 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),recvBuf); :PostMessage(hw

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

13、tDlg类在一个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 str=(char*)lParam; CSt

14、ring 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)强制转换为 (CIPAddressCtrl*)类型最后调用CIPAd

15、dressCtrl下的一个函数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; GetDlgItemText(IDC_EDIT_SEND

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

17、 device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); / Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Hei

18、ght() - cyIcon + 1) / 2; / Draw the icon dc.DrawIcon(x, y, m_hIcon); else CDialog: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:InitSocket() m_socket=socket(AF_

19、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*)&addrSock,sizeof(SOCKADDR); int retv

20、= 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 lpParameter; SOCKADDR_IN addrFrom; int len=s

21、izeof(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,WM_RECVDATA,0,(LPARAM)tempBuf); /发送数据 传送一个自定义消息,传给

22、窗口 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,strTemp); (CEdit*)GetDlgItem(IDC_EDIT_RECV)-LineScroll(CEdit*)GetD

23、lgItem(IDC_EDIT_RECV)-GetLineCount();void CChartDlg:OnButtonSend() / TODO: Add your control notification handler code here DWORD dwIP; ( (CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1) )-GetAddress(dwIP); SOCKADDR_IN addrTo; addrTo.sin_family=AF_INET; addrTo.sin_port=htons(1234); addrTo.sin_addr.S_un.S_

24、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!=)strTem

25、p+=rn; /增加一个换行 strTemp+=str; SetDlgItemText(IDC_EDIT_RECV,strTemp); (CEdit*)GetDlgItem(IDC_EDIT_RECV)-LineScroll(CEdit*)GetDlgItem(IDC_EDIT_RECV)-GetLineCount();LPCSTR CChartDlg:GethostIP() char name255; PHOSTENT hostinfo; LPCSTR ip; if(gethostname(name,sizeof(name)=0) /如果能获取计算机主机信息的话,则获取本机IP地址 if(h

26、ostinfo=gethostbyname(name)!=NULL) ip=inet_ntoa(*(struct in_addr*)*hostinfo-h_addr_list); return ip;三 . 注意事项:1 一定要保证 bind的端口和recvfrom的端口号一致;2 在绑定的IP地址设置中,如果只与本地进行通信,采用(127.0.0.1) 是可以的,但如果和其他网络的机器进行通信,必须写完整的机器IP,比如:(172.18.49.126);3 注意控件的ID要一致,比如这里的示例中:接受文本框的ID为IDC_EDIT_RECV,发送数据的文本框ID为IDC_EDIT_SEND,发送按钮的ID为IDC_BT。四 . 参考文献1 袁庆龙,候文义Ni-P合金镀层组织形貌及显微硬度研究太原理工大学学报,2001,32(1):51-53.(连续出版物:序号 主要责任者文献题名J刊名,出版年份,卷号(期号):起止页码)2刘国钧,王连成图书馆史研究北京:高等教育出版社,1979:15-18,31(专著:序号 主要责任者文献题名出版地:出版者,出版年:起止页码)3 孙品一高校学报编辑工作现代化特征中国高等学校自然科学学报研究会科技编辑学论文集(2)北京:北京师范大学出版社,1998:10-22(论文集:序号 主要责任者文献题名主编论文集名出版地:出版者,出版年:起止页码)

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1