UDP客户服务器应用程序设计_第1页
已阅读1页,还剩9页未读 继续免费阅读

下载本文档

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

文档简介

UDP客户/服务器应用程序设计 姓名:学号:班级: 目录一. 实验名称 3二. 实验要求 3三. 程序实现流程图 3四. 编程使用的主要函数 3五. 主要程序段及其功能 5六. 程序测试: 91. 正常绑定,正常通话: 9单播:<默认方式> 9广播: 112.异常绑定,异常通话: 123.程序特色: 12七. 实验收获 13 实验名称UDP客户/服务器应用程序设计实验要求编程实现一个聊天室系统。该系统包括客户端和服务器端两部分。用户通过客户端发送消息。服务器端在收到消息后,显示在主界面上。要求还能实现广播功能。实验报告要求有实现过程的流程图,对主要的函数及其参数给予说明,要有实现过程的主要程序段,并对各段程序的功能及作用进行说明。程序实现流程图编程使用的主要函数1.intWSAStartup(WORDwVersionRequested,LPWSADATAlpWSAData);初始化套接字库函数。使用Socket之前必须调用此函数,当一个应用程序调用WSAStartup函数时,操作系统根据请求的Socket版本来搜索相应的Socket库,然后绑定找到的Socket库到该应用程序中,以后应用程序就可以调用所请求的Socket库中的其它Socket函数了。参数wVersionRequested表示当前套接字库的版本号,参数lpWSAData是指向结构体WSADATA的指针变量,表示获取套接字库的详细信息,函数调用成功返回0。2.SOCKETsocket(intaf,inttype,intprotocol)创建网络通信套接字句柄。参数af指定套接字所使用的地址格式,对于TCP/IP协议族,该参数置PF_INET;type是表示套接字的类型,采用流套接字类型用SOCK_STREAM,数据报套接字类型使用SOCK_DGRAM;protocol表示应用程序使用的通讯协议,一般写0表示对两种类型的Socket分别采用默认的TCP或UDP传输协议,函数调用成功返回新建套接字的句柄,否则返回INVALID_SOCKET。3.intbind(SOCKETs,structsockaddr_in*name,intnamelen)绑定地址信息.对服务器而言套接字创建成功后,应将套接字与地址结构信息进行绑定,第一个参数s为套接字句柄,第二个参数地质结构信息,第三个参数地质结构的大小。调用成功返回0,失败返回SOCKET_ERROR。4.intsetsockopt(intsockfd,intlevel,intoptname,constvoid*optval,socklen_toptlen)套接字设置选项,可以设置广播发送方式。第一个参数是套接字描述符,第二个参数是选项定义的层次,目前仅支持SOL_SOCKET和IPPORT_TCP层次,第三个参数设置为SO_BROADCAST表示允许套接字传送广播信息,第四个参数是指针,指向存放选项值的缓冲区,最后一个参数表示此缓冲区的长度。设置成功返回0,失败返回SOCKT_ERROR。5.intsendto(SOCKETs,constcharFAR*buf,intlen,intflags,conststructsockaddrFAR*to,inttolen)实现服务器和客户端的数据发送。参数s是服务器或者是客户端套接字,buf应用程序发送的数据缓冲区,len实际发送数据长度,flags一般为0,表示表示只描述同步Socket的sendto函数的执行流程。后两个参数表示目标地址结构信息和目标地址结构大小。6.intrecvfrom(SOCKETs,constcharFAR*buf,intlen,intflags,conststructsockaddrFAR*to,inttolen)实现服务器和客户端的数据接收。参数s是服务器或者是客户端套接字,buf应用程序接收数据的缓冲区,len指定数据缓冲区长度,flags一般为0,表示表示只描述同步Socket的recvfrom()函数的执行流程。后两个参数表示目标地址结构信息和目标地址结构大小。7.intclosesocket(SOCKETs)关闭套接字函数。S表示即将关闭的套接字句柄。主要程序段及其功能备注:由于客户端和服务器大部分代码都相同,这里主要以服务器代码为例!//服务器地址信息的绑定:当点击确定按钮时,此函数开始绑定地址信息(绑定自身地址信息,等待接收对方的信息;同时将对方的地址信息绑定到地址结构信息中,用于发送信息)voidCTCPDlg::OnBind(){CStringstr; GetDlgItem(IDC_PORT)->GetWindowText(str);if(str=="") { MessageBox("端口号不能为空!"); }else {//绑定本机地址信息 port=atoi(str.GetBuffer(0)); addr.sin_family=AF_INET; addr.sin_addr.S_un.S_addr=INADDR_ANY; addr.sin_port=htons(port); if(bind(s,(sockaddr*)&addr,sizeof(addr))==SOCKET_ERROR) { MessageBox("绑定失败!"); return; }//设置套接字为广播发送if(setsockopt(s,SOL_SOCKET,SO_BROADCAST,(char*)&fBroadcast,sizeof(BOOL))==SOCKET_ERROR) {MessageBox("设置广播套接字失败!"); }//设置广播地址信息 addr2.sin_family=AF_INET; addr2.sin_addr.S_un.S_addr=INADDR_BROADCAST;addr2.sin_port=htons(9999);GetDlgItem(IDC_TEXT)->SetWindowText("地址信息绑定成功,请选择发送方式!\r\n"); if(::WSAAsyncSelect(s,this->m_hWnd,WM_SOCKET,FD_READ)>0) MessageBox("选择失败!"); GetDlgItem(IDC_SENDTEXT)->EnableWindow(true); GetDlgItem(IDC_SEND)->EnableWindow(true); GetDlgItem(IDC_ADDR)->EnableWindow(false); GetDlgItem(IDC_PORT)->EnableWindow(false); }}//服务器端数据的发送:由于UDP是面向无连接的,所以发送函数只需指定要发送的地址信息即可。voidCTCPDlg::OnSend(){CStringstr1,time1; CEdit*pEt=(CEdit*)GetDlgItem(IDC_TEXT); GetDlgItem(IDC_SENDTEXT)->GetWindowText(str1); char*p=str1.GetBuffer(str1.GetLength()+1); if(str1=="") { MessageBox("消息不能为空!"); } else {if(radio==2){ if(::sendto(s,p,str1.GetLength(),0,(sockaddr*)&addr1,sizeof(addr1))==SOCKET_ERROR) { MessageBox("消息发送失败!"); return; } } if(radio==1) { if(::sendto(s,p,str1.GetLength(),0,(sockaddr*)&addr2,sizeof(addr2))==SOCKET_ERROR) {MessageBox("广播信息发送失败!"); return; } } intnLen=pEt->SendMessage(WM_GETTEXTLENGTH);pEt->SetSel(nLen,nLen); time2=CTime::GetCurrentTime(); time1=time2.Format("%H:%M:%S"); time1+="\r\n"; if(radio==1) pEt->ReplaceSel("\r\n广播->我"+time1+str1); if(radio==2)pEt->ReplaceSel("\r\n单播->我"+time1+str1); GetDlgItem(IDC_SENDTEXT)->SetWindowText(NULL); }}//服务器端信息的接收:当有接收网络事件时,无论是客户端还是服务器都是使用相同的函数进行接收,只需指定套接字描述符和接受新存放的位置,以及存放对方IP地址信息的位置即可!LRESULTCTCPDlg::OnSocket(WPARAMwParam,LPARAMlParam){charcs[1024]={0}; CStringtime1; intlen=sizeof(addr2); CEdit*pEt=(CEdit*)GetDlgItem(IDC_TEXT); if(lParam==FD_READ) { CStringnum=""; intcou=::recvfrom(s,cs,1024,0,(sockaddr*)&addr2,&len); ::WSAAsyncSelect(s,this->m_hWnd,WM_SOCKET,FD_READ); cs[cou]=NULL; num+=(LPSTR)cs; time2=CTime::GetCurrentTime(); time1=time2.Format("%H:%M:%S"); intnLen=pEt->SendMessage(WM_GETTEXTLENGTH);pEt->SetSel(nLen,nLen);pEt->ReplaceSel("\r\n他"+time1+"\r\n"+num); } return0;}//定时器的实现:定时器的实现是通过调用系统消息函数OnTimer()实现,函数设置为SetTimer(1,1000,NULL),1为定时器的名字,第二参数表示每一秒钟响应一次,最后一个参数表示调用系统默认函数OnTiemer()(言外之意可以调用任意自己重写的函数),定时器的使用以及用变量的控制实现了间隔一段时间显示不同的字体不同的背景颜色.voidCTCPDlg::OnTimer(UINTnIDEvent){ defaulttime2=CTime::GetCurrentTime(); CStringtime1; if(k==0) { statu=::CreateStatusWindow(WS_CHILD|WS_VISIBLE,"欢迎使用TCP聊天工具--作者:201008202106谢明哲!",this->m_hWnd,IDC_ADDR); ::SendMessage(statu,SB_SETBKCOLOR,0,(long)RGB(255,204,255)); k++; } if(k==5) { statu=::CreateStatusWindow(WS_CHILD|WS_VISIBLE,"计算机网络编程作业",this->m_hWnd,IDC_ADDR); ::SendMessage(statu,SB_SETBKCOLOR,0,(long)RGB(255,255,153)); k=-4; } else k++; time2=CTime::GetCurrentTime(); time1=time2.Fo

温馨提示

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

评论

0/150

提交评论