计算机网络实验报告.doc

上传人:文库蛋蛋多 文档编号:2401308 上传时间:2023-02-17 格式:DOC 页数:13 大小:507.50KB
返回 下载 相关 举报
计算机网络实验报告.doc_第1页
第1页 / 共13页
计算机网络实验报告.doc_第2页
第2页 / 共13页
计算机网络实验报告.doc_第3页
第3页 / 共13页
计算机网络实验报告.doc_第4页
第4页 / 共13页
计算机网络实验报告.doc_第5页
第5页 / 共13页
点击查看更多>>
资源描述

《计算机网络实验报告.doc》由会员分享,可在线阅读,更多相关《计算机网络实验报告.doc(13页珍藏版)》请在三一办公上搜索。

1、青岛理工大学理学院电子信息与技术专业计算机网络实验报告指导教师:夏欣学生班级:电子082学生学号:200801108学生姓名:孙艳双报告完成日期:2011- 05-29 一、实验内容一1 实验要求:学会VC+串口上位机编程2 实施过程:程序的编写:1、 打开VC+6.0建立基于对话框的MFC应用程序Test,创建应用程序类型为:基本对话框,其他为默认设置,点击完成。 2、 在项目中插入MSComm控件:工程-增加到工程-Components and Controls-双击Registered ActiveX Controls-选择Microsoft Communications Control

2、, version 6.0-Insert,按默认值添加,你会发现多了个电话图标,这是增加后串口通信控件。3、 删除确认、取消和提示框,添加“电话”、进程、静态文本、按钮、编辑框,拖动添加的控件,根据喜好布局。4、 右击编辑框Edit选择属性,在样式里设置,勾选多行、垂直滚动,其它可按默认值。右击静态文本Text选择属性,在常规设置里,修改标题。右击按钮PushButton选择属性,在在常规设置里,修改标题。修改后界面如下,程序写出来运行时“电话”标志会自动消失。5、 查看-建立类向导MFC ClassWizard-Member Viariable,选择ClassName为CTestDlg的类,

3、Control ID为MSCOMM1,双击它,为它添加控制变量m_comm1。类似的,选择IDC_BUTTON2添加控制变量m_serial。(建立类向导也可以右击然后在弹出的快捷菜单里选择建立类向导)至此,基本框架已经出来了,编译后运行可以看到如下所示的界面。(组建-全部组件,然后 组建-执行)6、 点击左侧的视图窗口,可以在三种模式下切换,第三个是打开我们的源代码窗口,第一个是类,第二个是窗体的资源视图。选择File View,展开test files-Header Files,打开testDlg.h,在全局变量下添加如下代码,然后保存:int gllen;/定义整型标量gllen,用于记

4、录接收数据的个数CProgressCtrl * pbar; /指向进度条的指针,用于操作进度条CString strRXDdata; /编辑框显示的文本,记录历次转换值7、 点击Recourse View,展开test recourses-Dialog,双击IDD_TEST_DIALOG,编辑我们的主界面对话框。双击击“电话”,弹出如下对话框,按确认键:VC会进入源码编辑窗口,这个函数是用来处理串口事件的,当PC串口接收到数据时,会产生一个数据缓冲区有数据的消息事件,然后调用执行这个函数。添加如下代码,进行数据处理,窗口更新等操作:VARIANT variant1;/定义VARIANT型变量,

5、用于存放接收到的数据COleSafeArray safearray;/定义safearray型变量LONG len,k;/定义长整型变量len,kBYTE rxdata2048;/定义BYTE型数组CString stremp1,stremp2;/定义两个字符串if(m_comm1.GetCommEvent()=2) /判断引起OnComm时间的原因/如果是接收到特定个字节数,则读取接收到的数据variant1 = m_comm1.GetInput();/把接收到的数据存放到VARIANT型变量里safearray = variant1;/VARIANT型变量转换为ColeSafeArray型

6、变量len = safearray.GetOneDimSize();for(k=0;klen;k+) safearray.GetElement(&k,rxdata+k); /得到接接收到的数据放到BYTE型数组rxdata里for(k=0;klen;k+)BYTE bt = (*(unsigned char*)(rxdata+k); /读取AD转换的高字节if(k%2)=0)if(k+1)6); /高低字节合并成实际的转换结果,注意转换结果是左对齐 stremp1.Format(%2.2f,(2.56*temp/1024);/计算成实际电压值SetDlgItemText(IDC_STATIC,

7、(当前电压值为: +stremp1+ V); /更新静态文本控件pbar - SetPos(temp);/更新进度条的当前位置strRXDdata += stremp2;/把新的数据放到全局的字符串里 strRXDdata += stremp1;strRXDdata += Vrn;/字符串加单位V后换行SetDlgItemText(IDC_EDIT1,strRXDdata);/更新文本控件的显示这时重新编译一下,看会不会有什么错误,出现下面提示,可以选择全部组建来清除。LINK : LNK4073: cannot create map for .ILK file; linking noninc

8、rementally全部组建编译一下,看看有没有错误,没有错误就可以运行一下,可以看到界面更原来是一样的。8、 在源码编辑里,打开testDlg.cpp文件,进行窗口初始化函数的编写。找到BOOL CTestDlg:OnInitDialog()函数,在SetIcon(m_hIcon, FALSE); / Set small icon/ TODO: Add extra initialization here后面添加如下初始化代码:gllen = 0; /记录转换次数全局变量清零if(! m_comm1.GetPortOpen()/判断串口是否已经打开m_comm1.SetCommPort(1);

9、 /选择串口号1m_comm1.SetPortOpen(TRUE); /打开串口m_comm1.SetRThreshold(2); /收到两个字节引发OnComm事件m_comm1.SetInputMode(1);/输入模式选为二进制m_comm1.SetSettings(57600,n,8,1); /设置串口参数,波特率57600,无奇偶校验,1位停止位,8位数据位MessageBox(串口初始化完毕,提示); /提示串口成功初始化else MessageBox(串口被占用,提示); /如果已经打开串口,消息框提醒pbar = (CProgressCtrl*)GetDlgItem(IDC_P

10、ROGRESS1);/获得指向IDC_PROGRESS1的指针pbar - SetRange(0,1023);/设置进度条的范围01023pbar - SetPos(0);/当前位置为0m_serial.SetWindowText(关闭串口);/按钮显示状态改变可以看到,串口的参数等等都在在这里初始化的,可以根据自己的需要修改的,具体可以查看VC+里的详细介绍,看看有哪些参数可以给我们修改来用。添加后再编译一下,运行后可以看到多了一个串口初始化的提示信息窗口。至此,我们已经完成了主要的串口操作及界面,剩下的就是两个按钮的操作了。9、 回到资源视图的IDD_TEST_DIALOG窗口,双击开始转

11、换按钮,给它添加事件,点击后PC通过串口发送0xaa出来,给单片机接收。添加如下代码:CByteArray m_Array; /定义字节数组m_Array.RemoveAll(); /字节数组清空m_Array.SetSize(1); /设定维数为1m_Array.SetAt(0,0xaa); /给m_array0赋值0m_comm1.SetOutput(COleVariant(m_Array);/由于SetOutput函数的参数为VARIANT型,必须强制转换后才能发送同样地,双击另外一个按钮,给串口操作按钮添加代码,用于关闭或者打开串口。添加如下代码:if(! m_comm1.GetPor

12、tOpen()/判断串口是否已经打开 m_comm1.SetPortOpen(TRUE); /如果串口是关闭的,则打开串口m_serial.SetWindowText(关闭串口); /按钮显示状态改变elsem_comm1.SetPortOpen(FALSE); /如果已经打开串口,则关闭串口m_serial.SetWindowText(打开串口);/按钮显示状态改变至此,一个简单的串口上位机软件编写完成了,可以用来测试下,通过单片机往串口里发送数据,可以看到主窗口的的转换结果,已经进度条显示电压值变化。要把这个程序拿出来用,只需把vc+串口上位机testRelease的test.exe拷出来

13、用就行。Release可以在编译窗口里选择win32 release,然后重新编译一下就出来了。3 最终完成情况:4 遇到的问题、调试及总结:第7步骤是可能会遇到一下问题:如果全部组建编译出现下面错误,请关闭运行的test.exe后重试。LINK : fatal error LNK1104: cannot open file Debug/test.exe出现下面错误两种错误,是由于空间编号问题引起的,当我们添加了编辑框或者“电话”后再添加,其编号自动加一,就会出现控件没定义。Z:vc+串口上位机testtestDlg.cpp(32) : error C2065: IDC_MSCOMM1 : u

14、ndeclared identifierZ:vc+串口上位机testtestDlg.cpp(139) : error C2065: IDC_EDIT1 : undeclared identifier解决方法是,在RecourseView里,打开窗体IDD_TEST_DIALOG,右击“电话”或者编辑框等其它出错的控件,右击选择属性,在常规里修改ID,这里的程序,除BUTTON有1、2两个之外,其它都是1二、实验内容二1 实验要求:完成停止等待协议模拟2 实施过程:实验步骤:1 建立基于对话框的project2 加入edit框两个,按钮一个(可以把按钮命名为“copy”)3 完成任务为控制编辑框

15、:单击“copy”按钮即可实现把一个对话框的内容copy到另外一个对话框中具体实现方法:a 给两个编辑框添加成员变量,(我们可以先添加为string类型),分别名为m_input, m_output b 在单击“copy”按钮的函数里面添加UpdateData(true); m_output=m_input; UpdateData(false); c 编译运行,在m_input 所对应的edit中输入数据,点击“copy”按钮,即可实现3中功能4 实现串口通信:添加一个“发送“按钮。然后,请按照给大家的文件说明去做。注意文件中给出的程序应该放在哪里,不要乱放。另外,修改一些程序后,及时的编译,

16、如果不能通过编译,可以及时修改,避免改的程序多了,不知道哪里出了问题。5 实现数据链路层的停止-等待协议。协议流程图及说明在下面。发送方,在用户点击“发送”按钮后,并不是直接把数据送到串口,而是首先构成帧,然后发送数据。接受方收到数据后,不直接把数据显示到编辑框中,而是采用停止等待协议的方法去测试数据的正确与否,正确在送到编辑框中显示,并回送确认信息;否则按照协议发否认信息。对数据链路层的协议3编程,针对上面的图给出的流程图。a 发送方流程图(按发送按钮后的程序,即在单击发送按钮的函数中)b接收方流程图(在串口事件函数中)c源代码发送端:(client.cpp)#include #includ

17、e #include #pragma comment(lib,Ws2_32.lib) #define SERVER_PORT7300 /侦听端口客户端向服务器传送的结构:struct BAGchar packet;void main(int argc, char *argv)WORD wVersionRequested;WSADATA wsaData;int ret,i,ra,data=0;SOCKET sClient,sListen; struct sockaddr_in saServer;/地址信息struct BAG bag;char *ptr = (char *)&bag;BOOL f

18、Success = TRUE;WinSock初始化:wVersionRequested = MAKEWORD(2, 2);/希望使用的WinSock DLL的版本ret = WSAStartup( wVersionRequested, &wsaData );if (ret != 0)printf(WSAStartup() failed!n);return;确认WinSock DLL支持版本2.2:if (LOBYTE(wsaData.wVersion) != 2 | HIBYTE( wsaData.wVersion ) != 2 )WSACleanup();printf(Invalid Win

19、sock version!n);return;创建socket,使用TCP协议:sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if(sClient = INVALID_SOCKET)WSACleanup();printf(socket() failed!n);return;构建服务器地址信息:saServer.sin_family = AF_INET;/地址家族saServer.sin_port = htons(SERVER_PORT

20、);/转化为网络字节序连接服务器:ret = connect(sClient, (struct sockaddr *)&saServer, sizeof(saServer);if (ret = SOCKET_ERROR)printf(connect() successed!n);closesocket(sClient);/关闭套接字WSACleanup();return;按照预定协议,客户端将发送一个数字:for(i=97;i=104;i+)ra = rand()%11;if(ra%5 = 1) data+=i;else data=i;bag.packet=data;ret = send(sC

21、lient, (char *)&bag, sizeof(bag), 0);ret = recv(sListen, ptr, sizeof(bag), 0);if(bag.packet!=i)i-;printf(send()successed!n);continue;else if(bag.packet=i)printf(packet %d has been sent!n,i+1);closesocket(sClient);WSACleanup();接受端(server.cpp):#include #include #include #include #pragma comment(lib,Ws

22、2_32.lib) #define SERVER_PORT7300 /侦听端口客户端向服务器传送的结构:struct BAGchar packet;void main()WORD wVersionRequested;WSADATA wsaData;int ret,nLeft,length;SOCKET sListen, sServer; /侦听套接字,连接套接字struct sockaddr_in saServer, saClient;/地址信息struct BAG bag;char *ptr,*pp;WinSock初始化:wVersionRequested = MAKEWORD(2, 2);

23、/希望使用的WinSock DLL的版本ret = WSAStartup(wVersionRequested, &wsaData);if (ret != 0)printf(WSAStartup() failed!n);return;确认WinSock DLL支持版本2.2:if (LOBYTE(wsaData.wVersion) != 2 | HIBYTE( wsaData.wVersion ) != 2 )WSACleanup();printf(Invalid Winsock version!n);return;创建Socket,使用TCP协议:sListen = socket(AF_INE

24、T, SOCK_STREAM, IPPROTO_TCP);if(sListen = INVALID_SOCKET)WSACleanup();printf(socket() failed!n);return;构建本地地址信息:saServer.sin_family = AF_INET;/地址家族saServer.sin_port = htons(SERVER_PORT);/转化为网络字节序saServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);/使用INADDR_ANY指示任意地址绑定:ret = bind(sListen, (struct socka

25、ddr *)&saServer, sizeof(saServer);if (ret = SOCKET_ERROR)printf(bind() failed! code:%dn, WSAGetLastError();closesocket(sListen);/关闭套接字WSACleanup();return;侦听连接请求:ret = listen(sListen, 5);if (ret = SOCKET_ERROR)printf(listen() failed! code:%dn, WSAGetLastError();closesocket(sListen);/关闭套接字WSACleanup()

26、;return;printf(Waiting for client connecting!n);printf(tips : Ctrl+c to quit!n);阻塞等待接受客户端连接:length = sizeof(saClient);sServer = accept(sListen, (struct sockaddr *)&saClient, &length);if(sServer = INVALID_SOCKET)printf(accept() failed! code:%dn, WSAGetLastError();closesocket(sListen);/关闭套接字WSACleanup

27、();return;printf(Accepted client: %s:%dn, inet_ntoa(saClient.sin_addr), ntohs(saClient.sin_port);按照预定协议,客户端将发来一个信息:nLeft = sizeof(bag);ptr = (char *)&bag;for(int i=97;i=104;i+)接收数据:pp=ptr;ret = recv(sServer, ptr, nLeft, 0);if(ret = SOCKET_ERROR)printf(recv() failed!n);break;else if(bag.packet!=i)pri

28、ntf(wrong packet!n);i-;ret = send(sServer, pp, nLeft, 0); continue;else if(bag.packet=i)printf(recv() %c successd!n,i);ret = send(sServer, ptr, nLeft, 0);客户端已经关闭连接:if(ret = 0) printf(client has closed the connection!n);break;closesocket(sListen);/关闭套接字closesocket(sServer);WSACleanup();3 最终完成情况:服务器端的运行截图:客户端的运行截图:结果如下所示:客户端:服务器端:4 遇到的问题、调试及总结:停止等待协议是数据链路层的一个重要协议,也是计算机网络中的一个重要协议。在进行课程设计时我遇到了不少的困难,通过同学的帮助和查阅相关的资料,最终解决了问题,模拟实现了停止等待协议。在设计过程中,刚开始时,没有能够实现客户端和服务器的连接,最终导致客户端发送数据的失败,从而导致服务器端的接收失败。经过查阅相关的资料,找到了错误的所在,并实现了停止等待协议的功能。此外,此次课程设计中的一个难点就是客户端发送数据采用的是随机函数rand()产生随机发送的数据。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号