通信网原理实验报告.docx
- 文档编号:24520087
- 上传时间:2023-05-28
- 格式:DOCX
- 页数:26
- 大小:307.66KB
通信网原理实验报告.docx
《通信网原理实验报告.docx》由会员分享,可在线阅读,更多相关《通信网原理实验报告.docx(26页珍藏版)》请在冰豆网上搜索。
通信网原理实验报告
中南大学
“通信网原理”实验报告
第一次实验
实验名称:
应用层协议分析及编程实现
专业班级:
电子信息1003班
学生姓名:
刘素凯
学号:
0909102207
指导教师:
陈科文
实验日期:
2012年11月15日
实验名称
应用层协议分析与编程实现
一.实验目的和要求
1.实验目的
(1)通过实验,进一步加深理解 Web(WWW)、FTP、Email 等常用网络应用服务的基本概念与工作原理;
(2)在理解 HTTP、FTP、POP3、SNMP 等应用层协议设计思想的基础上,初步掌握应用层协议(如 HTTP 协议)的编程实现方法;
(3)熟练掌握基于 Socket 的网络通信程序设计方法。
2.实验要求
(1)熟悉基于 Socket 的网络通信程序设计方法,学习并掌握任意一种应用层协议(如 HTTP协议)的编程实现方法(其余协议的编程实现也可采用类似方法并参照相应协议的具体细节 );
(2)编写一个简单的 WWW(或 FTP)客户机程序,它能够向指定地址的 WWW(或FTP)服务器发送请求命令,并能接收服务器返回的响应数据。
该程序能够把客户和服务器之间相互传递的报文内容显示出来,以供用户进行分析;
(3)实验程序必须调试成功,并接受教师验收;
(4)按要求撰写《实验报告》(参阅本指导书的附录一“实验报告内容与格式”),并按时提交报告。
二.实验关键技术(包括编程环境和关键 API 函数简介,以及程序设计基本思想,比如要解决的关键问题、工作流程,或主要数据结构的定义、算法的描述)
1.编程环境:
VisualC++6.0
VisualC++6.0是一款可视化的C、C++编译环境,并且它提供的MFC可以帮助我们快速的建立一个工程项目,在此基础上进行编程,大大的降低了开发难度与周期,是一款效率比较高的编译软件。
2.编译关键技术:
基于Socket的网络编程
WindowsSocket规范定义了一套MicrosoftWindows下的网络编程接口,它不仅包含了人们所熟悉的BerkeleySocket风格的库函数;也包含了一组针对Windows的扩展库函数,以使程序员能充分地利用Windows消息驱动机制进行编程。
在一个特定版本Windows的基础上,WindowsSockets也定义了一个二进制接口(ABI),以此来保证应用WindowsSocketsAPI的应用程序能够在任何网络软件供应商的符合WindowsSockets协议的实现上工作。
应用程序调用WindowsSockets的API实现相互之间的通讯。
WindowsSockets又利用下层的网络通讯协议功能和操作系统调用实现实际的通讯工作。
3.API关键函数
(1)WSAStartup函数
IntWSAStartup(WORDwVersionRequested,LPWSADATAlpWSAData);
使用Socket的程序在使用Socket之前必须调用WSAStartup函数。
该函数的第一个参数指明程序请求使用的Socket版本,其中高位字节指明副版本、低位字节指明主版本;操作系统利用第二个参数返回请求的Socket的版本信息。
当一个应用程序调用WSAStartup函数时,操作系统根据请求的Socket版本来搜索相应的Socket库,然后绑定找到的Socket库到该应用程序中。
以后应用程序就可以调用所请求的Socket库中的其它Socket函数了。
该函数执行成功后返回0。
(2)WSACleanup函数
IntWSACleanup(void);
应用程序在完成对请求的Socket库的使用后,要调用WSACleanup函数来解除与Socket库的绑定并且释放Socket库所占用的系统资源。
(3)socket函数
SOCKETsocket(intaf,inttype,intprotocol);
应用程序调用socket函数来创建一个能够进行网络通信的套接字。
第一个参数指定应用程序使用的通信协议的协议族,对于TCP/IP协议族,该参数置PF_INET;第二个参数指定要创建的套接字类型,流套接字类型为SOCK_STREAM、数据报套接字类型为SOCK_DGRAM;第三个参数指定应用程序所使用的通信协议。
该函数如果调用成功就返回新创建的套接字的描述符,如果失败就返回INVALID_SOCKET。
套接字描述符是一个整数类型的值。
每个进程的进程空间里都有一个套接字描述符表,该表中存放着套接字描述符和套接字数据结构的对应关系。
该表中有一个字段存放新创建的套接字的描述符,另一个字段存放套接字数据结构的地址,因此根据套接字描述符就可以找到其对应的套接字数据结构。
每个进程在自己的进程空间里都有一个套接字描述符表但是套接字数据结构都是在操作系统的内核缓冲里。
(4)closesocket函数
Intclosesocket(SOCKETs);
Closesocket函数用来关闭一个描述符为s套接字。
由于每个进程中都有一个套接字描述符表,表中的每个套接字描述符都对应了一个位于操作系统缓冲区中的套接字数据结构,因此有可能有几个套接字描述符指向同一个套接字数据结构。
套接字数据结构中专门有一个字段存放该结构的被引用次数,即有多少个套接字描述符指向该结构。
当调用closesocket函数时,操作系统先检查套接字数据结构中的该字段的值,如果为1,就表明只有一个套接字描述符指向它,因此操作系统就先把s在套接字描述符表中对应的那条表项清除,并且释放s对应的套接字数据结构;如果该字段大于1,那么操作系统仅仅清除s在套接字描述符表中的对应表项,并且把s对应的套接字数据结构的引用次数减1。
Closesocket函数如果执行成功就返回0,否则返回SOCKET_ERROR。
(5)send函数
Intsend(SOCKETs,constcharFAR*buf,intlen,intflags);
不论是客户还是服务器应用程序都用send函数来向TCP连接的另一端发送数据。
客户程序一般用send函数向服务器发送请求,而服务器则通常用send函数来向客户程序发送应答。
该函数的第一个参数指定发送端套接字描述符;第二个参数指明一个存放应用程序要发送数据的缓冲区;第三个参数指明实际要发送的数据的字节数;第四个参数一般置0。
(6)recv函数
Intrecv(SOCKETs,charFAR*buf,intlen,intflags);
不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据。
该函数的第一个参数指定接收端套接字描述符;第二个参数指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;第三个参数指明buf的长度;第四个参数一般置0。
(7)bind函数
Intbind(SOCKETs,conststructsockaddrFAR*name,intnamelen);
当创建了一个Socket以后,套接字数据结构中有一个默认的IP地址和默认的端口号。
一个服务程序必须调用bind函数来给其绑定一个IP地址和一个特定的端口号。
(8)listen函数
Intlisten(SOCKETs,intbacklog);
服务程序可以调用listen函数使其流套接字s处于监听状态。
处于监听状态的流套接字s将维护一个客户连接请求队列,该队列最多容纳backlog个客户连接请求。
假如该函数执行成功,则返回0;如果执行失败,则返回SOCKET_ERROR。
(9)accept函数
SOCKETaccept(SOCKETs,structsockaddrFAR*addr,intFAR*addrlen);
服务程序调用accept函数从处于监听状态的流套接字s的客户连接请求队列中取出排在最前的一个客户请求,并且创建一个新的套接字来与客户套接字创建连接通道,如果连接成功,就返回新创建的套接字的描述符,以后与客户套接字交换数据的是新创建的套接字;如果失败就返回INVALID_SOCKET。
该函数的第一个参数指定处于监听状态的流套接字;操作系统利用第二个参数来返回新创建的套接字的地址结构;操作系统利用第三个参数来返回新创建的套接字的地址结构的长度。
(10)connect函数
Intconnect(SOCKETs,conststructsockaddrFAR*name,intnamelen);
客户程序调用connect函数来使客户Sockets与监听于name所指定的计算机的特定端口上的服务Socket进行连接。
如果连接成功,connect返回0;如果失败则返回SOCKET_ERROR。
4.程序设计基本思想
(1)建立控制连接
FTP协议在传输层采用的是TCP协议。
在FTP客户机与服务器之间通信,第一步是建立两者之间的控制连接。
首先,FTP客户机调用socket()函数建立套接字,SOCK_STREAM表示流式套接字;然后,FTP客户机填充服务器的套接字地址,其中的地址填写FTP服务器的IP地址,端口填写FTP服务器控制连接的常用端口21。
接着,FTP客户机调用connect()函数请求与服务器建立连接;最后,FTP客户机接受与分析服务器返回的响应信息,FTP服务器可能返回的响应信息有120、220、421,只有接收到的响应信息为220时,才表示这个控制连接已经成功建立,可以通过该连接来发送FTP命令。
(2)登陆FTP服务器
FTP客户机与服务器建立控制连接之后,还要经过身份认证才能登陆FTP服务器,这时要验证用户名与密码的正确性。
登陆FTP服务器使用USER和PASS命令,他们分别用来输入用户名与密码。
USER和PASS命令是按规定顺序出现的。
FTP客户机向服务器发送USER命令,FTP服务器可能返回的响应有220、331、421、500、501、530,只有接受的信息为331时,才表示用户名正确并需要继续输入密码,FTP客户机向服务器发送PASS命令,FTP服务器可能返回的响应有230、332、421、500、501、530,只有接受到的响应信息为230时,才表示用户名和密码均正确并成功登录。
(3)列出FTP服务器目录
LIST命令用来返回当前目录中的信息,需要使用数据连接传输目录信息,我们可以采用两种方法建立数据连接:
PORT和PASV命令。
其中,PORT方式称为主动模式,FTP客户机指定用于数据连接的端口,由FTP服务器和客户机建立连接;PASV方式称为被动方式,FTP服务器在响应信息中指出用于数据连接的端口,由FTP客户机与服务器之间建立连接。
在这个例子中,采用的是PASV方式。
在LIST命令执行完之后,断开FTP客户机与服务器之间的数据连接,并且释放数据连接使用的套接字。
(4)退出FTP服务器
QUIT命令用于退出FTP服务器,FTP客户机向服务器发送QUIT命令,当FTP客户机接受的响应为221时,表示成功退出FTP服务器,这时,需要断开FTP客户机与服务器之间的控制连接,并且释放控制连接使用的套接字。
(5)执行顺序
第一步,FTP客户机程序初始化用户界面;
第二步,FTP客户机建立Winsock库绑定关系,并且创建控制连接与数据连接的流式套接字;
第三步,FTP客户机与服务器建立控制连接,依次发送USER和PASS命令,登录到FTP服务器;
第四步,FTP客户机发送PASV命令和LIST命令,建立数据连接、接受目录信息,与断开数据连接;
第五步,FTP客户机发送QUTI命令,断开控制连接;
第六步,FTP客户机释放流式套接字,并且解除Winsock库绑定关系。
三.实验操作过程(包括:
每一步实验内容、实验方法和中间结果,实验过程中遇到的问题及解决方法。
)
1.实验准备阶段:
在实验之前,我先阅读了实验要求,然后选择了实验的内容,编写一个FTP客户机程序。
接下来第一步,复习书本上所学到的关于FTP协议的理论内容,进一步理解FTP的基本概念和工作原理。
第二步,我熟悉了VisualC++6.0编译环境,以前只是会用它进行C程序的基本编译,都是DOS界面,没有用过MFC,现在学了一下MFC,学会了怎么去建立工程,了解Socket套接字,并且如何利用Socket去编写程序。
第三步,我开始阅读别人已经做过的实例作为参考,这样能够更加快速的学会如何去编写程序。
2.实验进行阶段:
第一步,先利用VisualC++提供的MFC建立一个工程项目。
如下图:
选择MFCAppWizard(exe),并进行相应的设置,生成一个工程项目,
如下图:
第二步,GUI界面的设计,设计一个美观人性化的人机交互界面。
结果如下图:
第三步,编写代码。
第四步,程序调试。
3.实验进行后
根据得到的实验结果,进一步理解了FTP协议,并且在编程的过程中,学习了VisualC++的使用,并且学习了基于Socket的网络编程技术,收获颇多。
最后一项工作,实验总结,撰写实验报告书。
4.遇到的问题及解决办法
这是我第一次用C++编程,以前也用过MicrosoftVisualC++6.0进行编程,但是用到的语言是C语言,而且人际交互界面都是DOS界面,没有设计过GUI界面,所以这次首当其冲的难题便是工程的建立。
为此,我查阅了相关资料,在网上找到资料,学习了如何利用VisualC++6.0提供的MFC来快速的建立工程项目,以及如何生成GUI界面,如何将GUI界面与函数联系起来。
之后的难题便是基于Socket的网络编程技术,以前没有涉及过这个概念,我按照老师的建议,参考了实验指导书上的代码,在编译调试过程中,实在调试不过的地方,去询问同学。
通过编程的过程,对FTP协议有了更加深刻的理解。
四.程序源代码(要求有良好的编程规范和必要的注释信息,完整源代码可打印并粘贴)
//FTPDlg.h:
头文件
#if!
defined(AFX_FTPDLG_H__043ACF11_6AB0_4A4C_AE94_85D4644C31BB__INCLUDED_)
#defineAFX_FTPDLG_H__043ACF11_6AB0_4A4C_AE94_85D4644C31BB__INCLUDED_
#if_MSC_VER>1000
#pragmaonce
#endif//_MSC_VER>1000
//CFTPDlgdialog
#defineMAX_SIZE4096
classCFTPDlg:
publicCDialog
{
public:
CFTPDlg(CWnd*pParent=NULL);//standardconstructor
enum{IDD=IDD_FTP_DIALOG};
CStringm_Address;
CStringm_Directory;
CStringm_Login;
CStringm_Account;
CStringm_Password;
protected:
virtualvoidDoDataExchange(CDataExchange*pDX);
protected:
HICONm_hIcon;
virtualBOOLOnInitDialog();
afx_msgvoidOnSysCommand(UINTnID,LPARAMlParam);
afx_msgvoidOnPaint();
afx_msgHCURSOROnQueryDragIcon();
afx_msgvoidOnConnect();
afx_msgvoidOnList();
afx_msgvoidOnQuit();
private:
boolDataConnect();
boolSendCommand();
boolRecvRespond();
charCommand[MAX_SIZE];
charRespond[MAX_SIZE];
intRespondCode;
SOCKETSocketControl;
SOCKETSocketData;
DECLARE_MESSAGE_MAP();
};
#endif
//程序代码
//FTPDlg.cpp:
implementationfile
//
#include"stdafx.h"
#include"FTP.h"
#include"FTPDlg.h"
#include"winsock.h"
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
classCAboutDlg:
publicCDialog
{
public:
CAboutDlg();
enum{IDD=IDD_ABOUTBOX};
protected:
virtualvoidDoDataExchange(CDataExchange*pDX);
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg:
:
CAboutDlg():
CDialog(CAboutDlg:
:
IDD)
{
}
voidCAboutDlg:
:
DoDataExchange(CDataExchange*pDX)
{
CDialog:
:
DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)
END_MESSAGE_MAP()
CFTPDlg:
:
CFTPDlg(CWnd*pParent/*=NULL*/):
CDialog(CFTPDlg:
:
IDD,pParent)
{
m_Address=_T("");
m_Directory=_T("");
m_Login=_T("");
m_Account=_T("");
m_Password=_T("");
//}}AFX_DATA_INIT
//NotethatLoadIcondoesnotrequireasubsequentDestroyIconinWin32
m_hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
voidCFTPDlg:
:
DoDataExchange(CDataExchange*pDX)
{
CDialog:
:
DoDataExchange(pDX);
DDX_Text(pDX,IDC_ADDRESS,m_Address);
DDX_LBString(pDX,IDC_LIST1,m_Directory);
DDX_LBString(pDX,IDC_LIST2,m_Login);
DDX_Text(pDX,IDC_ACCOUNT,m_Account);
DDX_Text(pDX,IDC_PASSWORD,m_Password);
}
BEGIN_MESSAGE_MAP(CFTPDlg,CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1,OnConnect)
ON_BN_CLICKED(IDC_BUTTON2,OnList)
ON_BN_CLICKED(IDC_BUTTON3,OnQuit)
END_MESSAGE_MAP()
BOOLCFTPDlg:
:
OnInitDialog()
{
CDialog:
:
OnInitDialog();
ASSERT((IDM_ABOUTBOX&0xFFF0)==IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX<0xF000);
CMenu*pSysMenu=GetSystemMenu(FALSE);
if(pSysMenu!
=NULL)
{
CStringstrAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if(!
strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
}
SetIcon(m_hIcon,TRUE);//Setbigicon
SetIcon(m_hIcon,FALSE);//Setsmallicon
returnTRUE;//returnTRUEunlessyousetthefocustoacontrol
}
voidCFTPDlg:
:
OnSysCommand(UINTnID,LPARAMlParam)
{
if((nID&0xFFF0)==IDM_ABOUTBOX)
{
CAboutDlgdlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog:
:
OnSysCommand(nID,lParam);
}
}
voidCFTPDlg:
:
OnPaint()
{
if(IsIconic())
{
CPaintDCdc(this);//devicecontextforpainting
SendMessage(WM_ICONERASEBKGND,(WPARAM)dc.GetSafeHdc(),0);
//Centericoninclientrectangle
intcxIcon=GetSystemMetrics(SM_CXICON);
intcyIcon=GetSystemMetrics(SM_CYICON);
CRectrect;
GetClientRect(&rect);
intx=(rect.Width()-cxIcon+1)/2;
inty=(rect.Height()-cyIcon+1)/2;
dc.DrawIcon(x,y,m_hIcon);
}
else
{
CDialog:
:
OnPaint();
}
}
HCURSORCFTPDlg:
:
OnQueryDragIcon()
{
return(HCURSOR)m_hIcon;
}
voidCFTPDlg:
:
OnConnect()//连接
{
WSADATAWSAData;
if(WSAStartup(MAKEWORD
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 通信网 原理 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)