计算机网络课设设计报告-VS2013_MFC基于对话框编程.docx_第1页
计算机网络课设设计报告-VS2013_MFC基于对话框编程.docx_第2页
计算机网络课设设计报告-VS2013_MFC基于对话框编程.docx_第3页
计算机网络课设设计报告-VS2013_MFC基于对话框编程.docx_第4页
计算机网络课设设计报告-VS2013_MFC基于对话框编程.docx_第5页
已阅读5页,还剩37页未读 继续免费阅读

下载本文档

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

文档简介

成绩: 2015-2016学年第2学期计算机网络课程设计DAY1:题目:VS2013/MFC基于对话框编程学院名称: 班级学号: 学生姓名: 教师姓名: 2016年 7 月 1. 创建MFC工程(1)双击打开 VS2013,进入起始页,在左侧开始处选择“新建项目”;或者选择菜单栏中“文件”,依次选择“新建”、“项目”。(2)选择新建项目后,在新建项目对话框中选择 模块-Visual C+-MFC-MFC应用程序,并确定好存放路径和项目名称,点击“确定”。 (3)进入应用程序向导,一开始会给出默认的项目配置,点击“下一步”即可。 (4)选择“基于对话框”,MFC可以选择在静态库中使用,或者在共享DLL中使用。一般选择共享使用就行,静态库中使用会把所有用到的 dll 集成到 exe 文件中,最终生成的文件一般可以直接使用,但占用更大空间。(5) 选择主框架样式,可以自由选择是否添加最小化框、最大化框。如果觉得没必要“关于”对话框也可以去掉,对话框标题一般不需要更改。 (6)高级功能一般默认即可,但如果用不上“ActiveX 控件”可以去掉勾选;如果需要涉及网络编程就把“windows 套接字”选上。不过没选上也不要紧,在程序中可以自己添加部分代码导入套接字。 (7)最后是自动生成的两个类的头文件和源文件名称,可以修改基类,但一般不用改,默认完成就行。至此,一个基于对话框的MFC项目就创建好了。 2. MFC执行流程(1)每创建一个项目,一般会包含 3 个类,“关于”对话框类、主对话框类以及用于初始化项目的 App 类,假如项目名称为 Demo,那么这三个类分别为 CAboutDlg、CDemoDlg、CDemoApp。 (2) 项目生成后,都会生成一个属于 CDemoApp 类的 theApp 对象,对本应用程序实例化,这个在CDemoApp.cpp文件中定义,创建时调用构造函数CDemoApp:CDemoApp();这就是程序创建的第一步。(3) 接下来程序会调用winmain函数,这个在项目文件中找不到,但可以在VS2013的安装路径下找到,其函数声明为: int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,_In_ LPTSTR lpCmdLine, int nCmdShow); (4) 调用完winmain后,就通过 InitInstance()函数初始化窗口,包括注册、创建和显示对话框,InitInstance函数是CDemoApp类中除构造函数以外唯一的成员函数。 一般不需要修改这部分程序,但有些时候可以添加部分代码,比如需要创建多个对话框时,刚启动时弹出的对话框(比如用于登录)不是主对话框,就可以在这个函数里创建主对话框之前调用登录对话框,这样就可以设置启动时的默认对话框了。 (5)应用程序创建完了,程序开始运行了,于是进入消息循环,windows程序的事件都是消息驱动 的,每产生一个消息就触发一个响应事件,消息和事件通过消息映射DECLARE_MESSAGE_MAP()联系在一起。 默认包含三个消息: ON_WM_SYSCOMMAND() /响应控制指令 ON_WM_PAINT() /响应绘图消息,用于刷新窗口 ON_WM_QUERYDRAGICON() /当用户拖动最小化窗口时取得光标 (6)当用户关闭应用程序时,会发送一个 WM_CLOSE 消息,程序响应后结束程序,如何在点击关闭时需要弹出其他对话框(比如用于提示保存),可以通过类向导添加 WM_CLOSE 消息处理函数,变添加相关处理程序,比如: void CDemoDlg:OnClose() if (MessageBox(_T(确定退出吗), _T(提示), MB_YESNO|MB_ICONWARNING) = IDNO) return; CDialogEx:OnClose(); (7) 这样,一个应用程序通过定义,初始化,由winmain开始,注册、创建、显示窗口,消息响应,程序终止 完成了他的运行周期。 3. 对话框类(1) 首先看看对话框类的继承关系,新建的项目类派生于CDialogEx类,CDialogEx在CDialog类的基础上进行了扩展,而CDialog派生于窗口类CWnd,说明对话框也属于一种窗口。这样对于对话框类的继承关系就有了一定了解。 (2) 打开项目的头文件,最上面的#pragma once表示后面的头文件只编译一次;默认生成的函数有: CDemoDlg(CWnd* pParent = NULL); / 标准构造函数 virtual void DoDataExchange(CDataExchange* pDX); / DDX/DDV 支持 / 生成的消息映射函数 virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() / 消息映射的声明 三个消息在前一经验已经介绍过,构造函数自然是创建对话框时自动调用, DoDataExchange函数用于存放各类控件的变量信息,OnInitDialog用来初始化对话框。(3) 打开源文件可以看到各个函数的定义,“关于”对话框类的成员函数和消息映射也在这里,不多述。先讲述构造函数 CDemoDlg(),通过类向导生成的自定义变量或者控件的关联变量都会在构造函数中初始化一个值,不过开发者也可以直接在头文件定义变量,并手动在构造函数中添加初始化语句。 所以说,构造函数是个赋初值的好地方。 (4) 再来看 DoDataExchange 函数,在对话框中添加新的控件并通过类向导定义了相关变量后,都会在这个用于数据交换的函数中说明,添加变量的最大最小值也会在这里体现。 (5) 下面是消息映射,定义了所有消息的来源和处理函数,对于自定义消息或者某些无法通过类向导完成的消息,可以手动在这里添加映射关系,并在别处添加对应的处理函数。(6) 初始化函数OnInitDialog,默认用来设置图标和菜单,很多时候有些操作需要在启动对话框前就做好,比如说某些控件的初始状态(按钮是否可视、是否可操作),这些初始化的设置都可以在OnInitDialog函数中添加,最 好 在提示语“/ TODO: 在此添加额外的初始化代码”的下面添加。 (7) 系统指令响应函数 OnSysCommand,默认处理窗口最小化和最大化指令等,并会根据是否选中“关于”决定是否弹出“关于”对话框。这个函数一般不需要修改。(8) 绘图消息响应函数OnPaint 用于绘制窗口和图标,其中CRect是个存储窗口大小的结构体。OnQueryDragIcon函数用于返回光标,这不多讲。 (9) 默认生成的函数就这么多,其他常用的消息有定时器消息 WM_TIMER、窗口关闭消息WM_CLOSE、应用程序结束消息 WM_DESTROY、按钮按下消息 WM_KEYDOWN 等。而常用的虚函数一般有PreTranslateMessage、PreCreateWindow等,这些以后用到再具体说明。 4. 按钮的使用 按钮(Button)可以说是对话框中最常用的控件之一,也是人机交互中必不可少的控件之一。许多事件都是通过按钮按下来触发的。(1) 在工具箱中找到对话框,按钮名称是Button。把对话框原有的按钮和静态文本删除,从工具箱中添加两个按钮到对话框中。 (2) 选中任意一个按钮,在属性页中可以查看按钮的所有属性。 一般需要修改的属性只有两个,“Caption”项和“ID”项,前者表示按钮文本,后者是按钮ID,就像是人的身份证号一样是唯一的。 其余常用属性: 1、Disabled:使能,为真(true)表示按钮可以按下,为假(false)表示按钮为灰,不能操作 2、Visible:可见,为真表示按钮可见,为假表示按钮不可见 3、Multiline:多行,为真表示按钮文本可以多行显示,为假表示按钮文本不可换行显示 说明:对于只有真假两种选项的属性,可以双击属性名称进行切换true或false。选中属性名称,在属性页最下方都会有属性说明。 说明: 1、变量名一般以m_开头,后面部分为按钮功能的说明,这样方便记忆和识别; 2、按钮只有控件型的变量; 3、如果有必要的话可以添加一定的注释。5. 编辑框 编辑框(Edit Control)作为对话框中常用的控件之一,常用来输入文本或者显示文本,比如用户名和密码的输入,当前数据的显示等等都少不了编辑框。 (1) 从工具箱中找到编辑框(Edit Control),拖动到对话框中。(2) 首先选中任意一个编辑框,看看编辑框都有哪些属性,其中常用到属性有: Multiline:多行,表示内容可以多行显示,一般记录性的编辑框需要多行; Password:密码,表示文本以密码形式呈现,一般用来输出密码; Read only:只读,表示文本内容只能读不能写; Number:数字,表示只能输入数字; Lowercase:小写,所有字母全部自动转换为小写显示; Uppercase:大写,所有字母全部自动转换为大写显示; Horizontal scroll:水平滚动条,需要先选中Multiline属性; Vertical scroll:垂直滚动条,需要先选中Multiline属性;11 成绩: 2015-2016学年第2学期计算机网络课程设计DAY2:题目:SOCKET编程学院名称: 班级学号: 学生姓名: 教师姓名: 2016年 7 月 1. Socket简介 80年代初,美国政府的高级研究工程机构(ARPA)给加利福尼亚大学Berkeley分校提供了资金,让他们在UNIX操作系统下实现TCP/IP协议。在这个项目中,研究人员为TCP/IP网络通信开发了一个API(应用程序接口)。这个API称为Socket接口(套接字)。今天,SOCKET接口是TCP/IP网络最为通用的API,也是在INTERNET上进行应用开发最为通用的API。 90年代初,由Microsoft联合了其他几家公司共同制定了一套WINDOWS下的网络编程接口,即WindowsSockets规范。它是BerkeleySockets的重要扩充,主要是增加了一些异步函数,并增加了符合Windows消息驱动特性的网络事件异步选择机制。WINDOWSSOCKETS规范是一套开放的、支持多种协议的Windows下的网络编程接口。从1991年的1.0版到1995年的2.0.8版,经过不断完善并在Intel、Microsoft、Sun、SGI、Informix、Novell等公司的全力支持下,已成为Windows网络编程的事实上的标准。目前,在实际应用中的WINDOWSSOKCETS规范主要有1.1版和2.0版。两者的最重要区别是1.1版只支持TCP/IP协议,而2.0版可以支持多协议。2.0版有良好的向后兼容性,任何使用1.1版的源代码,二进制文件,应用程序都可以不加修改地在2.0规范下使用。SOCKET实际在计算机中提供了一个通信端口,可以通过这个端口与任何一个具有SOCKET接口的计算机通信。应用程序在网络上传输,接收的信息都通过这个SOCKET接口来实现。在应用开发中就像使用文件句柄一样,可以对SOCKET句柄进行读,写操作。Socket可以支持数据的发送和接收,它会定义一种称为套接字的变量,发送数据时首先创建套接字,然后使用该套接字的sendto等方法对准某个IP/端口进行数据发送;接收端也首先创建套接字,然后将该套接字绑定到一个IP/端口上,所有发向此端口的数据会被该套接字的recv等函数读出。如同读出文件中的数据一样。2. 所需的头文件、库文件和DLL对于目前使用最广泛的Windows Socket2.0版本,所需的一些文件如下(以安装了VC6为例说明其物理位置):l头文件winsock2.h,通常处于C:Program FilesMicrosoft Visual StudioVC98INCLUDE;查看该头文件可知其中又包含了windows.h和pshpack4.h头文件,因此在windows中的一些常用API都可以使用;l库文件Ws2_32.lib,通常处于C:Program FilesMicrosoft Visual StudioVC98Lib;lDLL文件Ws2_32.dll,通常处于C:WINDOWSsystem323. 部分类型与函数1) SOCKET类型 SOCKET是socket套接字类型,在WINSOCK2.H中有如下定义: typedef unsigned int u_int; typedef u_intSOCKET; 可知套接字实际上就是一个无符号整型,它将被Socket环境管理和使用。套接字将被创建、设置、用来发送和接收数据,最后会被关闭。2) WORD 类型 WORD类型是一个16位的无符号整型,在WTYPES.H中被定义为: typedef unsigned short WORD;其目的是提供两个字节的存储,在Socket中这两个字节可以表示主版本号和副版本号。3) WSADATA类型WSADATA类型是一个结构,描述了Socket库的一些相关信息,其结构定义如下:typedef struct WSAData WORDwVersion; WORDwHighVersion; charszDescriptionWSADESCRIPTION_LEN+1; charszSystemStatusWSASYS_STATUS_LEN+1; unsigned shortiMaxSockets; unsigned shortiMaxUdpDg; char FAR *lpVendorInfo; WSADATA;typedef WSADATA FAR *LPWSADATA;值得注意的就是wVersion字段,存储了Socket的版本类型。LPWSADATA是WSADATA的指针类型。它们不用程序员手动填写,而是通过Socket的初始化函数WSAStartup读取出来。4) Socket函数 socket的创建函数,其定义为: SOCKET PASCAL FAR socket (int af, int type, int protocol); 第一个参数为int af,代表网络地址族,目前只有一种取值是有效的,即AF_INET,代表internet地址族; 第二个参数为int type,代表网络协议类型,SOCK_DGRAM代表UDP协议,SOCK_STREAM代表TCP协议; 第三个参数为int protocol,指定网络地址族的特殊协议,目前无用,赋值0即可。返回值为SOCKET,若返回INVALID_SOCKET则失败。5) sockaddr_in、in_addr类型,inet_addr、inet_ntoa函数 sockaddr_in定义了socket发送和接收数据包的地址,定义: struct sockaddr_in short sin_family; u_short sin_port; structin_addr sin_addr; charsin_zero8; ; 其中in_addr的定义如下: struct in_addr union struct u_char s_b1,s_b2,s_b3,s_b4; S_un_b; struct u_short s_w1,s_w2; S_un_w; u_long S_addr; S_un; 首先阐述in_addr的含义,很显然它是一个存储ip地址的联合体,有三种表达方式:u 第一种用四个字节来表示IP地址的四个数字;u 第二种用两个双字节来表示IP地址;u 第三种用一个长整型来表示IP地址。 给in_addr赋值的一种最简单方法是使用inet_addr函数,它可以把一个代表IP地址的字符串赋值转换为in_addr类型,如 addrto.sin_addr.s_addr=inet_addr(192.168.0.2); 其反函数是inet_ntoa,可以把一个in_addr类型转换为一个字符串。 sockaddr_in的含义比in_addr的含义要广泛,其各个字段的含义和取值如下: 第一个字段short sin_family,代表网络地址族,如前所述,只能取值AF_INET; 第二个字段u_short sin_port,代表IP地址端口,由程序员指定; 第三个字段structin_addr sin_addr,代表IP地址; 第四个字段char sin_zero8,很搞笑,是为了保证sockaddr_in与SOCKADDR型的长度相等而填充进来的字段。 以下代表指明了广播地址,端口号为7861的一个地址: sockaddr_in addrto;/发往的地址 memset(&addrto,0,sizeof(addrto); addrto.sin_family = AF_INET; /地址类型为internetwork addrto.sin_addr.s_addr = INADDR_BROADCAST; /设置ip为广播地址 addrto.sin_port = htons(7861); /端口号为78616) 发送和接收函数 在Socket中有两套发送和接收函数,一是sendto和recvfrom;二是send和recv。前一套在函数参数中要指明地址;而后一套需要先将套接字和一个地址绑定,然后直接发送和接收,不需绑定地址。sendto的定义如下:int PASCAL FAR sendto (SOCKET s, const char FAR * buf, int len, int flags, const struct sockaddr FAR *to, int tolen);第一个参数就是套接字;第二个参数是要传送的数据指针; 第三个参数是要传送的数据长度(字节数); 第四个参数是传送方式的标识,如果不需要特殊要求则可以设置为0,其它值请参考MSDN;第五个参数是目标地址,注意这里使用的是sockaddr的指针;第六个参数是地址的长度;返回值为整型,如果成功,则返回发送的字节数,失败则返回SOCKET_ERROR。send和recv是用来发送和接收数据的两个重要函数。send只能在已经连接的状态下使用,而recv可以面向连接和非连接的状态下使用。send的定义如下:int WSAAPI send(SOCKET s,const char FAR * buf, int len,int flags);其参数的含义和sendto中的前四个参数一样。而recv的定义如下:int WSAAPI recv(SOCKET s,char FAR * buf, int len,int flags);其参数含义与send中的参数含义一样。7 成绩: 2015-2016学年第2学期计算机网络课程设计DAY3:题目:服务器端、客户端设计学院名称: 班级学号: 学生姓名: 教师姓名: 2016年 7 月 1. 设计原理2. 具体设计(1)socket函数:为了执行网络输入输出,一个进程必须做的第一件事就是调用socket函数获得一个文件描述符。#include int socket(int family,int type,int protocol); 返回:非负描述字成功-1失败第一个参数指明了协议簇,目前支持5种协议簇,最常用的有AF_INET(IPv4协议)和AF_INET6(IPv6协议);第二个参数指明套接口类型,有三种类型可选:SOCK_STREAM(字节流套接口)、SOCK_DGRAM(数据报套接口)和SOCK_RAW(原始套接口);如果套接口类型不是原始套接口,那么第三个参数就为0。(2)connect函数:当用socket建立了套接口后,可以调用connect为这个套接字指明远程端的地址;如果是字节流套接口,connect就使用三次握手建立一个连接;如果是数据报套接口,connect仅指明远程端地址,而不向它发送任何数据。#include int connect(int sockfd, const struct sockaddr * addr, socklen_t addrlen); 返回:0成功-1失败第一个参数是socket函数返回的套接口描述字;第二和第三个参数分别是一个指向套接口地址结构的指针和该结构的大小。 这些地址结构的名字均已“sockaddr_”开头,并以对应每个协议族的唯一后缀结束。以IPv4套接口地址结构为例,它以“sockaddr_in”命名,定义在头文件;以下是结构体的内容:struct in_addr in_addr_t s_addr; /* IPv4地址 */;struct sockaddr_in uint8_t sin_len; /* 无符号的8位整数 */sa_family_t sin_family;/* 套接口地址结构的地址簇,这里为AF_INET */in_port_t sin_port; /* TCP或UDP端口 */struct in_addr sin_addr;char sin_zero8; ;(3)bind函数:为套接口分配一个本地IP和协议端口,对于网际协议,协议地址是32位IPv4地址或128位IPv6地址与16位的TCP或UDP端口号的组合;如指定端口为0,调用bind时内核将选择一个临时端口,如果指定一个通配IP地址,则要等到建立连接后内核才选择一个本地IP地址。#include int bind(int sockfd, const struct sockaddr * server, socklen_t addrlen);返回:0成功-1失败第一个参数是socket函数返回的套接口描述字;第二和第第三个参数分别是一个指向特定于协议的地址结构的指针和该地址结构的长度。(4)listen函数:listen函数仅被TCP服务器调用,它的作用是将用sock创建的主动套接口转换成被动套接口,并等待来自客户端的连接请求。#include int listen(int sockfd,int backlog); 返回:0成功-1失败第一个参数是socket函数返回的套接口描述字;第二个参数规定了内核为此套接口排队的最大连接个数。由于listen函数第二个参数的原因,内核要维护两个队列:以完成连接队列和未完成连接队列。未完成队列中存放的是TCP连接的三路握手为完成的连接,accept函数是从以连接队列中取连接返回给进程;当以连接队列为空时,进程将进入睡眠状态。(5)accept函数:accept函数由TCP服务器调用,从已完成连接队列头返回一个已完成连接,如果完成连接队列为空,则进程进入睡眠状态。#include int accept(int listenfd, struct sockaddr *client, socklen_t * addrlen); 回:非负描述字成功-1失败 第一个参数是socket函数返回的套接口描述字;第二个和第三个参数分别是一个指向连接方的套接口地址结构和该地址结构的长度;该函数返回的是一个全新的套接口描述字;如果对客户段的信息不感兴趣,可以将第二和第三个参数置为空。(6)write和read函数:当服务器和客户端的连接建立起来后,就可以进行数据传输了,服务器和客户端用各自的套接字描述符进行读/写操作。因为套接字描述符也是一种文件描述符,所以可以用文件读/写函数write()和read()进行接收和发送操作。 write()函数用于数据的发送。 #include int write(int sockfd, char *buf, int len); 返回:非负成功-1失败参数sockfd是套接字描述符,对于服务器是accept()函数返回的已连接套接字描述符,对于客户端是调用socket()函数返回的套接字描述符;参数buf是指向一个用于发送信息的数据缓冲区;len指明传送数据缓冲区的大小。 read()函数用于数据的接收。 #include int read(int sockfd, char *buf, intlen); 返回:非负成功-1失败参数sockfd是套接字描述符,对于服务器是accept()函数返回的已连接套接字描述符,对于客户端是调用socket()函数返回的套接字描述符;参数buf是指向一个用于接收信息的数据缓冲区;len指明接收数据缓冲区的大小。(7)send和recv函数:TCP套接字提供了send()和recv()函数,用来发送和接收操作。这两个函数与write()和read()函数很相似,只是多了一个附加的参数。send()函数用于数据的发送。#include #include ssize_t send(int sockfd, const void *buf, size_t len, int flags); 返回:返回写出的字节数成功-1失败前3个参数与write()相同,参数flags是传输控制标志。 recv()函数用于数据的发送。 #include #include ssize_t recv(int sockfd, void *buf, size_t len, int flags); 返回:返回读入的字节数成功-1失败前3个参数与read()相同,参数flags是传输控制标志。6 成绩: 2015-2016学年第2学期计算机网络课程设计题目:多终端数据采集系统的设计与实现学院名称: 班级学号: 学生姓名: 教师姓名: 2016年 7 月 一、实验要求 (1)按照所给出的通信协议格式,利用 UDP 通信,实现多终端数据采集并显示【必做项】; (2)进一步可以在服务器中各终端上传数据进行数据库保存,在此基础上开发基于网页或手机 APP 的多终端数据实时监控;【选做项】 (3)根据自己所设计实现的任务,完成课程设计报告。 二、 终端与服务器之间通信协议 (1)帧格式(固定部分 13B+数据部分帧长) 信息头2B版本号1B帧长2B类型1B帧号1B数据校验和4B结束标志 2B0xFFFFCRC320xFFF7其中: 帧号,取值范围 1255;一般一种命令包组织成一个帧,也可以称其为逻辑帧,内 容强调其逻辑上的完整性。 版本号,1 字节,缺省为 0. 帧长:为每个物理帧的数据部分长度,即有效位长度,整个帧长-13(固定部分长 度),一般其取值为 0490。2 字节。 类型:保留,缺省值 1。 校验和:CRC32 校验,只是对版本号到数据部分的字节内容加校验,即信息头和 结束标志部分不在校验之列,校验算法见本文档最后部分。 (2) 命令帧(即帧的数据部分) 终端ID5B命令1B数据其中: 终端 ID:5 个字节的 BCD 编号。 命令:小于 128,大于 128 为异常命令,即异常命令=0x80+命令。 (3) 终端与服务器之间通信流程 终端上传数据包给服务器,服务器接收,发送确认包给终端(4) 终端-服务器命令 序号 数据包类型 序号数据包类型命令码 1B说明1数据上传数据包0x13网络其中数据上传数据包格式如下 命令码 1B上传记录数 1B上传数据0x13n110按时间升序排列的采集状态数据42*n 所上传的 42 字节状态数据的组织结构表 名称类型字节数备注1采集时间byte6YYMMDDhhmmss2经度字节数组51字节符号位(0正1 负)+1字节整数+3字节小数(BCD编码),东经正数,西经为负数3纬度字节数组51字节符号位(0正1 负)+1字节整数+3字节小数(BCD编码)4水温字节数组4Real,缺省值05PH值字节数组4Real,缺省值06电导率字节数组4Real,缺省值07浊度字节数组4Real,缺省值08溶解氧字节数组4Real,缺省值09氨氮字节数组4Real,缺省值010上传标志byte10:未上传,1:已上传,缺省 011故障代码byte1位号:0:Modbus 故障,1:上传故障,2:连接管理服务器故障,3:位移报警,4:停电故障,5:系统故障。42(5) 服务器-终端命令列表 序号 数据包类型 序号数据包类型命令码 1B说明1确认包0x13网络其中确认包格式如下 命令码 1B帧号 1B发送方时间 7B0x13被确认的帧号YYYYMMDDhhmmss(BCD码) (6) 终端与服务器通信过程的说明: l l 终端每隔一定时间(默认为 10 秒)发送一个数据上传包,服务器收到数据上传包后,返回确认包; l l 服务器在规定的数据上传等待计时长度时间内(默认为 1 分钟)没有收到终端的任何信息,则认为该终端不在线(即离线)。 l l 如果终端在规定的时间内(默认为 5 秒)没有收到服务器确认包,则重发该上传数据包,每个上传数据包最多重发一次,还是没收到确认的话则丢去,延时 30 秒再发送下一个上传数据包。 l l 终端与服务器通信采用 UDP 方式。 (7) 数据帧校验和计算方法三、实现方案新建两个基于对话框的工程,分别为服务器、客户端。(1) 服务器端界面设计 在服务器端添加两个Edit:一个显示窗口IDC_EDIT1(点击右键选择Properties-Styles,选中Multiline,Vertical scroll、Read-only三项),一个输入窗口IDC_EDIT2。然后增加一个发送按钮:IDC_BtnSend,名称为发送。(2) 客户端界面设计 在客户端端添加三个Edit:一个显示窗口IDC_EDIT1(点击右键选择Properties-Styles,选中Multiline,Vertical scroll、Read-only三项),一个输入窗口IDC_EDIT2,一个IP地址输入窗口IDC_EDIT3。再增加两个按钮:一个发送按钮IDC_SEND,名称为发送,一个连接服务器按钮IDC_btnConnect,名称为连接服务器。(3) 代码实现(见附录1)四、测试结果 正常接收状态 关闭服务器后五、总结与展望这次课程设计和之前大不相同,很多知识都是第一次接触,例如MFC、SOCKET网络编程等等。一开始无从下手,只能先从网络上学习这些知识,而时间又比较紧迫,所以起初进度缓慢。待得初步熟悉了这些新知识以后,回过来再看这次课设就不再是那么迷茫了,有了一个大概的思路之后,设计也进入了正轨,从对话框设计再到服务器端客户端设计,虽然过程不是一帆风顺,但也是逐步推进。大体设计结束之后,进行调试,错误百出,由于学习得不是很深入,很多错误改起来也很棘手,尤其是各类数据类型之间的转换错误特别的多,百度、请教,各种尝试,花费了很长一段时间才把程序修改成功。初次调试,虽然没有语法上的错误,但因为逻辑错误,两端无法连接,初次调试以失败告终。不得不返回程序继续去修改。主要的错误是两端的IP地址不同,以及接收发送字符串长度有错。经过多次调试,程序最终成功了。对于这个设计,也有一些不足,服务器和客户端与现实中的功能有所差异,多客户端与服务器发送消息之间存在问题,还有待改进。总的而言,这次计算机网络课设收获颇丰,知识上学到了网络编程,学会如何设计一个简单的服务器端和客户端实现两端通信。以后踏入社会岗位最重要的是一个人的自学能力,尤其计算机这个行业技术日新月异,是离不开不断地学习的,这次的课设就完美地锻炼了我们的自学和动手能力,对于未来的就业和科研都有着重大意义。附录1(只附上添加的代码,自动生成的不在其内)1) 服务器端:1、 在stdafx.h中添加 #include/ MFC socket extensions 在服务器Dlg.h中添加public:void update(CString s); 在服务器Dlg.h中添加private:CEdit*show_edit;CEdit*send_edit;2、在服务器Dlg.cpp中添加#include (加在#include stdafx.h之前) #include tchar.h #pragma comment(lib,WS2_32.lib) 新建两个socket:SOCKET listen_sock; SOCKET sock; 声明线程函数 UINT server_thd(LPVOID p);3、在OnInitDialog()函数中添加: show_edit = (CEdit *)GetDlgItem(IDC_EDIT1);send_edit = (CEdit *)GetDlgItem(IDC_EDIT2);send_edit-SetFocus();char name80;CString IP;hostent* pHost;gethostname(name, 128);/获得主机名 pHost = gethostbyname(name);/获得主机结构 IP = inet_ntoa(*(in_addr *)pHost-h_addr);update(本机IP地址: + IP);AfxBeginThread(&server_thd, 0);return TRUE; / 除非将焦点设置到控件,否则返回 TRUE /添加函数update() void C服务器Dlg:update(CString s) show_edit-ReplaceSel(s + rn); /添加线程函数server_thd() UINT server_thd(LPVOID p) WSADATA wsaData; WORD wVersion; wVersion = MAKEWORD(2, 2); WSAStartup(wVersion, &wsaData); / WSAStartup(0x0202, &wsaData); SOCKADDR_IN local_addr; SOCKADDR_IN client_addr; int iaddrSize = sizeof(SOCKADDR_IN); int res; char msg1024; C服务器Dlg * dlg = (C服务器Dlg *)AfxGetApp()-GetMainWnd(); local_addr.sin_family = AF_INET; local_addr.sin_port = h

温馨提示

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

评论

0/150

提交评论