资源预览内容
第1页 / 共19页
第2页 / 共19页
第3页 / 共19页
第4页 / 共19页
第5页 / 共19页
第6页 / 共19页
第7页 / 共19页
第8页 / 共19页
第9页 / 共19页
第10页 / 共19页
亲,该文档总共19页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
“TCP/IP 协议及网络编程技术”课程实验报告 第 1 页,共 19页局域网文件传输实验报告实验名称:编写局域网内进行文件传输的小工具 实验目的:通过编写局域网内文件传输的工具,熟悉基于 UDP 的 Socket 编程,熟悉Winsock 的相关内容。对套接字编程有一定的理解和应用。实验内容:本小组最终结果实现的实验内容:完成基本任务要求:输入对方 IP 地址,对方如果存在,可以给对方发送文件。完成扩展任务要求:1 工具具有图形交互界面;2 局域网内使用该工具的两台主机可以互相进行文字通信;3 自动按照一定频率扫描局域网内其他开启了该工具的主机, 并在界面上用列表显示出来;4 传输文件和文字内容时,直接选择界面上已经显示出来的存活主机,不需要手动输入 IP 地址。实验准备说明:操作系统:Windows XP开发语言:C+,MFC开发平台:Microsoft Visual C+ 6.0由于开发图形界面时需要用到 MFC,因此对缺乏 MFC 编译运行环境的VC6 可能需要加载相应的动态链接库 DLL 文件。“TCP/IP 协议及网络编程技术”课程实验报告 第 2 页,共 19页加载方法:将 DLL 文件置放于系统链接库路径。即:C:WINDOWSsystem32实验设计与开发:程序设计思路:程序所采用基于 TCP/IP 协议的 Winsock 编程原理,编程模型采用客户机/服务器(Client/Server)方式,为了方便使用,设计将客户机和服务器合而为一。 在通信的时候主要可以分为两个部分,一个部分是用于传送控制信息,例如发送文件的请求,文件的名称、大小等,由于这方面的数据量比较小,为了方便起见采用了 MFC 所提供的 CSocket 类的串行化技术来实现;而另一个部分就是文件的传输部分,对于文件的传输,由于数据量相对来说比较大,所以分别写了两个线程,一个用于发送,一个用于接收。在添加附加功能聊天时,将聊天相关内容作为小文件传输,并将其显示在相应的控件中。这两个部分在具体实现的时候分别建立有自己的套接字(Socket) 。程序代码内容大体分为图形界面和后台交互两个模块,在最开始设计开发时原本准备以此作为分工,但实际图形界面代码较少,而且主要的复杂点在于事件响应和句柄绑定,比较容易解决,总体工作量较少,因此图形界面后来是共同讨论开发,设计完成后根据具体的控件响应分工相关联的后台交互代码开发。1.图形界面:程序采用单一界面工作模式,因此所有代码都集中于以 FileTransfersDlg 命名的.h 和.cpp 文件中。这样设计在一定程度上改善后期调试的复杂度。由于需要实现附加功能,最后图形界面所用控件较多,并且每个控件都有响应的消息映射,统计内容,整理如下表:表 1 控件响应消息映射表控件 ID 关联函数 功能描述IDC_RADIO_SERVER OnRadioServer() 服务端设置IDC_RADIO_CLIENT OnRadioClient() 客服端设置“TCP/IP 协议及网络编程技术”课程实验报告 第 3 页,共 19页IDC_BEGIN OnBegin()服务端为启动功能,客服端为连接功能IDC_DISCONNECT OnDisconnect()服务端为关闭功能,客服端为断开功能IDC_SELECT_FILE OnSelectFile() 选择文件IDC_STOP_TRANSFERS OnStopTransfers 停止传输IDC_TRANSFILE_RATIO OnTransfileRatio 文件传输模式IDC_CHAT_RATIO OnChatRatio 聊天模式IDC_SEND_MESSAGE OnSendMessage() 发送聊天信息IDC_ALLIP_ONLINE OnSelchangeAllipOnline() 获取在线服务器IDCANCEL OnCancel() 退出程序另外还有些用于显示相关内容的控件,这里不再列举。2.后台交互:2.1.主要线程后台交互代码主要为相应控件的响应函数和线程函数。所有代码中涉及了 4个线程:_ScanReceiveThread,_ScanDelieveThread,_ListenThread,_SendThread。具体功能列表如下:线程名 功能_ScanDelieveThread作为服务端时按一定时间间隔重复发送局域网广播包,为客户端提供在线服务端 IP 地址_ScanReceiveThread作为客户端时重复监听局域网广播包,获得在线服务端 IP 地址_ListenThread接收点对点文件线程,重复监听获取并接收获取文件(聊天)信息链接_SendThread发送点对点文件线程,当需要发送文件(聊天)信息时开启“TCP/IP 协议及网络编程技术”课程实验报告 第 4 页,共 19页_ScanDelieveThread 和_ScanReceiveThread 为广播包套接字,核心在于设置套接字地址格式。核心代码如下:_ScanDelieveThread:SOCKET sockClient = socket(AF_INET,SOCK_DGRAM,0); /初始化套接字,注意格式SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_BROADCAST); /设置广播地址addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(8000); /设置端口BOOL bOpt = TRUE; setsockopt(sockClient, SOL_SOCKET, SO_BROADCAST, (char*)&bOpt, sizeof(bOpt);/设置套接字格式,尤其是第三个参数:SO_BROADCASTZeroMemory(addrSrv.sin_zero,sizeof(addrSrv.sin_zero);bind(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR);/为套接字绑定固定的 IP 地址和端口,此处 IP 地址为广播地址: 255.255.255.255sendto(sockClient,sldkfjslfjslksdjfsdl,20,0,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR);/发送套接字,“sldkfjslfjslksdjfsdl”为发送消息,第五个参数比较重要closesocket(sockClient);/关闭套接字,此处比较重要,尤其是 while(1)循环中_ScanReceiveThread:char Buf100; /接收广播包 char 数组SOCKADDR_IN saRemote; /接收广播包地址INT nFrmSize = sizeof(saRemote); /地址大小,固定SOCKET sockClient = socket(AF_INET,SOCK_DGRAM,0); /初始化套接字SOCKADDR_IN addrSrv; /套接字地址WORD Port; /接收端口格式addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY); /设置接收套接地址格式,此处为局域网内任意地址“TCP/IP 协议及网络编程技术”课程实验报告 第 5 页,共 19页addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(8000); /套接字端口,此处应该和_ScanDelieveThread 中套接字端口相同ZeroMemory(addrSrv.sin_zero,sizeof(addrSrv.sin_zero);bind(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR); /绑定 IP 地址和端口memset(Buf,0,sizeof(Buf);int nErrCode = recvfrom(sockClient, Buf, 100, 0, (SOCKADDR *)(&saRemote), &nFrmSize);/接收广播包数据,其中 Buf 接收信息,saRemote 接收源地址的 IP 地址及端口信息,此处实际代码应该根据 nErrCode 有效性进行判断Port = ntohs(saRemote.sin_port); /得出源地址端口信息Cstring IP = inet_ntoa(saRemote.sin_addr); /得出源地址 IP 地址由于此处_ScanReceiveThread 和_ScanDelieveThread 两个进程一直处于激活状态,所以应该设置 while(1)或 for(;)循环,而且_ScanDelieveThread 应该对所得到的 IP 地址进行处理,代码中进入函数 ScanOnlineIp(char *ipAddress)。ScanOnlineIp(char *ipAddress)功能有两个主要功能:判断当前广播包地址是否为本机地址,判断当前广播地址是否已添加。具体代码通过设置一个vertor OnlineIp 处理,代码流程如下:if (conventIP != localIP) /判断是否为本机地址if (OnlineIp.empty() /vector 为空,当前无 IP 地址,添加操作 elsefor (int ix=0;ix!=OnlineIp.size();+ix) /循环遍历 vector 值if (conventIP=OnlineIpix) /相等说明改地址已经添加,设置标签 exist =TRUE; if (!exist) /如果标签为假,执行 IP 地址添加操作 而_ListenThread 和_SendThread 属于固定 IP 地址套接字。核心代码如下:“TCP/IP 协议及网络编程技术”课程实验报告 第 6 页,共 19页_ListenThread:CSocket sockSrvr; if(!sockSrvr.Create(pDlg-m_wPort + PORT) /创建套接字 if(!sockSrvr.Listen() /开始监听 CSocket recSo;if(!sockSrvr.Accept(recSo) /接收连接 sockSrvr.Close(); /关闭套接字_SendTh
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号