通信协议与网络程序设计实验指导书.docx

上传人:b****8 文档编号:9209487 上传时间:2023-02-03 格式:DOCX 页数:61 大小:174.57KB
下载 相关 举报
通信协议与网络程序设计实验指导书.docx_第1页
第1页 / 共61页
通信协议与网络程序设计实验指导书.docx_第2页
第2页 / 共61页
通信协议与网络程序设计实验指导书.docx_第3页
第3页 / 共61页
通信协议与网络程序设计实验指导书.docx_第4页
第4页 / 共61页
通信协议与网络程序设计实验指导书.docx_第5页
第5页 / 共61页
点击查看更多>>
下载资源
资源描述

通信协议与网络程序设计实验指导书.docx

《通信协议与网络程序设计实验指导书.docx》由会员分享,可在线阅读,更多相关《通信协议与网络程序设计实验指导书.docx(61页珍藏版)》请在冰豆网上搜索。

通信协议与网络程序设计实验指导书.docx

通信协议与网络程序设计实验指导书

网络程序设计实验指导书

 

电子与信息学院

2008年10月

 

《网络程序设计》实验指导书

一、说明

本实验指导书根据《网络程序设计》教学大纲和实验大纲编写。

前2个实验为练习性实验,旨在让学生在熟悉开发工具的环境和使用,熟悉套接字编程的基本原理。

后面的各个实验主要让学生理解各协议的工作原理,掌握相应应用程序的实现过程。

二、实验目的

通过实验,使学生熟悉并掌握计算机网络编程的基本知识,加深对课堂教学内容的理解,掌握基本的编程技巧,使学生能够进行一些简单的网络程序设计。

三、实验安排

《网络程序设计》实验部分共有9实验,每个实验占用2学时。

具体安排如下:

实验一、熟悉开发工具(2课时)

实验二、套接字编程练习(2课时)

实验三、TCP套接字编程(2课时)

实验四、UDP组播程序编程(2课时)

实验五、windowssocketsAPI练习(2课时)

实验六、聊天室程序的设计及实现(2课时)

实验七、PING程序的设计及实现(2课时)

实验八、电子邮件程序的设计与实现(SMTP客户端、POP3客户端程序)(2课时)

实验九、FTP客户端实现(2课时)

实验一熟悉开发工具

一、实验目的

通过编写简单的Windows窗口、基于MFC的计算器以及车站售票程序(多线程实现),深入了解VC++的开发环境,掌握常用的控件使用方法和程序编写过程。

二、实验内容

1.开发简单的Windows窗口

2.开发MFC下的程序界面,实现计算器,能进行运算。

3.开发一个多线程的例子:

车站售票程序。

三、实验环境

Windows操作系统、VC++6.0

四、实验指导

1.利用WindowsAPI函数编写Windows应用程序必须首先了解以下内容:

(1)窗口的概念

(2)事件驱动的概念

(3)句柄

(4)消息

2.Windows应用程序常用消息

(1)WM_LBUTTONDOWN:

产生单击鼠标左键的消息

(2)WM_KEYDOWN:

按下一个非系统键时产生的消息

(3)WM_CHAR:

按下一个非系统键时产生的消息

(4)WM_CREATE:

由CreateWindow函数发出的消息

(5)WM_CLOSE:

关闭窗口时产生的消息

(6)WM_DESTROY:

由DestroyWiodow函数发出的消息

(7)WM_QUIT:

由PostQuitMessage函数发出的消息

(8)WM_PAINT

3.Windows应用程序组成及编程步骤

(1)应用程序的组成

●C语言源程序文件

●头文件

●模块定义文件

●资源描述文件

●项目文件

(2)源程序组成结构

入口函数WinMain

窗口函数WndProc

①入口函数WinMain

●WinMain函数的说明如下:

intWINAPIWinMain

(HINSTANCEhThisInst,∥应用程序当前实例句柄

HINSTANCEhPrevInst,∥应用程序其他实例句柄

LPSTRlpszCmdLine,∥指向程序命令行参数的指针

IntnCmdShow∥应用程序开始执行时窗口显示方式的整数值标识

●初始化

●消息循环

消息循环的常见格式如下:

MSGMsg;

while(GetMessage(&Msg,NULL,0,0))

{TranslateMessage(&Msg);

DispatchMessage(&Msg);}

②窗口函数的一般形式如下:

LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessgae,

WPARAMwParam,LPARAMlParam)

{…

switch(message)∥message为标识的消息

{case…

break;

caseWM_DESTROY:

PostQuitMessage(0);

default:

returnDefWindowProc(hwnd,message,wParam,lParam);

}

return(0);

2.多线程

(1)HANDLECreateThread(

                                                   LPSECURITY_ATTRIBUTESlpThreadAttributes,

                                                   SIZE_TdwStackSize,

                                                    LPTHREAD_START_ROUTINElpStartAddress,

                                                   LPVOIDlpParameter,

                                                   DWORDdwCreationFlags,

                                                   LPDWORDlpThreadId

);

A:

第三个参数是个函数指针,指向某种特定的函数,调用约定是WINAPI//#defineWINAPI__stdcall,    参数LPVOID保障了函数的合法性.

B:

次函数两个得到两个值:

第一个值是HANDLE,大部分和线程有关的API函数都要使用它;第二个是参数ThreadID带回来的值,它是独一无二的表示一个进程中的某个线程.

说明:

我们不可以从一个线程的ID从而得到其HANDLE.

(2)BOOLCloseHandle(

           HANDLEhObject

);

用来释放核心对象。

(3)创建一个新的线程

要创建一个线程,必须得有一个主进程,然后由这个主进程来创建一个线程,在一般的VC程序中,主函数所在的进程就是程序的主进程。

让我们从主函数来开始编写我们这个简单的小程序。

我们知道CreateThread函数可以用来创建一个线程,在MSDN中查找这个函数得到如下信息:

"TheCreateThreadfunctioncreatesathreadtoexecutewithintheaddressspaceofthecallingprocess."和"Ifthefunctionsucceeds,thereturnvalueisahandletothenewthread."所以我们得定义一个句柄用来存放它的返回值。

还定义一个指向线程ID的DWORD值dwThreadId。

然后我们就可以用CreateThread函数来创建我们的线程了,CreateThread函数有六个参数分别是

LPSECURITY_ATTRIBUTESlpThreadAttributes, //pointertosecurityattributes

DWORDdwStackSize,                        //initialthreadstacksize

LPTHREAD_START_ROUTINElpStartAddress,    //pointertothreadfunction

LPVOIDlpParameter,                       //argumentfornewthread

DWORDdwCreationFlags,                    //creationflags

LPDWORDlpThreadId                        //pointertoreceivethreadID

其中第一个参数我们设置为NULL,使这个句柄不能被继承;第二个参数设置为0,使用默认的堆栈大小;第三个参数为线程函数的起始地址,也就是线程函数的函数名;第四个参数为NULL,没有值要传递给线程函数;第五个参数为0,创建好之后马上让线程运行;第六个参数设置为指向线程ID的地址。

创建好线程之后,线程函数进行初始化之类的操作,主函数继续执行,此时可以输出被创建线程的ID。

我们在主函数中用WaitForSingleObject函数来等待线程函数变成受信(signaled)状态,它的两个参数分别是

 HANDLEhHandle,       //handletoobjecttowaitfor

 DWORDdwMilliseconds  //time-outintervalinmilliseconds

第一参数为线程函数的句柄,第二个参数设置为INFINITE,等待线程一直执行完。

在程序的最后还要记得用CloseHandle函数关闭线程,这样主函数就写完了。

在线程函数里面我们可以简单地做一些工作,比如设置一个循环,让它输出一定的信息等。

源程序如下:

#include

#include

DWORDWINAPIThreadFunc(HANDLEThread)

{

 inti;

 for(i=0;i<10;i++)

 {

  cout<<"Anewthreadhascreated!

"<

 }

 return0;

}

intmain(intargc,char*argv[])

{

 HANDLEThread;

 DWORDdwThreadId;

 Thread=:

:

CreateThread

  (NULL,0,ThreadFunc,NULL,0,&dwThreadId);

 cout<<"ThenewthreadIDis:

"<

 :

:

WaitForSingleObject(Thread,INFINITE);

 :

:

CloseHandle(Thread);

 return0;

}

五、实验报告要求

1.实验名称

2.实验目的

3.实验内容

4.测试数据和预期结果(必要时应准备多组数据)

5.算法分析和流程图

6.源程序(应加适当的注释,可读性好)

7.小结(出错及解决方法,上机调试的结果和体会)

 

实验二套接字编程练习

一、实验目的

通过在SDK模式下完成数据通信的过程,掌握WindowsSocket的常用函数的形式和使用方法,理解数据通信的过程。

二、实验内容

1.Winsock的启动与终止。

2.Winsock的创建及绑定和关闭。

3.建立通信连接listen及accept和connect。

4.数据的传输。

5.简单的客户机/服务器之间的通信。

三、实验环境

Windows操作系统、VC++6.0

四、实验指导

在WINDOWS95/98,WINDOWSNT进行WINSOCK开发使用的编程语言有很多,VC++,JAVA,DELPHI,VB等。

其中VC时使用最普遍,和WINSOCK结合最紧密的。

并且VC++对原来的WindowsSockets库函数进行了一系列封装,继而产生了CAsynSocket、CSocket、CSocketFile等类,它们封装着有关Socket的各种功能,是编程变得更加简单。

但如果你是一个WINSOCK编程的初学者,那么建议你在一开始还是学习WINSOCK最基本的API函数进行编程,这样可以大大加深对WINSOCK的了解,对将来很有好

处。

在VC中进行WINSOCK的API编程开发,需要使用到下面三个文件:

1.WINSOCK.H:

这是WINSOCKAPI的头文件。

2.WSOCK32.LIB:

WINSOCKAPI连接库文件。

在使用中,一点要把它作为项目的非缺省的连接库包含到项目文件中去。

3.WINSOCK.DLL:

WINSOCK的动态连接库,位于WINDOWS的安装目录下。

WINSOCK.DLL位于TCP/IP协议栈和应用程序之间。

也就是说,WINSOCK管理与TCP/IP协议的接口。

在一开始WINSOCK的应有开发时,你不必对TCP/IP协议有很深刻的了解。

但是,如果想成为一个为网络编程的高手,就一定要对下层了解得十分清楚。

总的来说,使用SOCKET接口(面向连接或无连接)进行网络通信时,必须按下面简单的四步进行处理:

1.程序必须建立一个SOCKET。

2.程序必须按要求配置此SOCKET。

也就是说,程序要么将此SOCKET连接到远方的主机上,要么给此SOCKET指定一个本地协议端口。

3.程序必须按要求通过此SOCKET发送和接收数据。

4.程序必须关闭此SOCKET。

(一)WinSock原理

1.客户机/服务器模式

  在TCP/IP网络中两个进程间的相互作用的主机模式是客户机/服务器模式(Client/Servermodel)。

该模式的建立基于以下两点:

(1)非对等作用;

(2)通信完全是异步的。

客户机/服务器模式在操作过程中采取的是主动请示方式:

  首先服务器方要先启动,并根据请示提供相应服务:

(过程如下)

 

(1)打开一通信通道并告知本地主机,它愿意在某一个公认地址上接收客户请求。

 

(2)等待客户请求到达该端口。

 (3)接收到重复服务请求,处理该请求并发送应答信号。

 (4)返回第二步,等待另一客户请求

 (5)关闭服务器。

  客户方:

 

(1)打开一通信通道,并连接到服务器所在主机的特定端口。

 

(2)向服务器发送服务请求报文,等待并接收应答;继续提出请求……

 (3)请求结束后关闭通信通道并终止。

2.基本套接字

  为了更好说明套接字编程原理,给出几个基本的套接字,在以后的篇幅中会给出更详细的使用说明。

 创建套接字──socket()

应用程序在使用套接字前,首先必须拥有一个套接字,系统调用socket()

向应用程序提供创建套接字的手段,其调用格式如下:

 SOCKETsocket(intaf,inttype,intprotocol);

该调用要接收三个参数:

af、type、protocol。

参数af指定通信发生的区域,UNIX系统支持的地址族有:

AF_UNIX、AF_INET、AF_NS等,而DOS、WINDOWS中仅支持AF_INET,它是网际网区域。

因此,地址族与协议族相同。

参数type描述要建立的套接字的类型。

参数protocol说明该套接字使用的特定协议,如果调用者不希望特别指定使用的协议,则置为0,使用默认的连接模式。

根据这三个参数建立一个套接字,并将相应的资源分配给它,同时返回一个整型套接字号。

因此,socket()系统调用实际上指定了相关五元组中的“协议”这一元。

指定本地地址──bind()

当一个套接字用socket()创建后,存在一个名字空间(地址族),但它没有被命名。

bind()将套接字地址(包括本地主机地址和本地端口地址)与所创建的套接字号联系起来,即将名字赋予套接字,以指定本地半相关。

其调用格式如下:

intbind(SOCKETs,conststructsockaddrFAR*name,intnamelen);

参数s是由socket()调用返回的并且未作连接的套接字描述符(套接字号)。

参数name是赋给套接字s的本地地址(名字),其长度可变,结构随通信域的不同而不同。

namelen表明了name的长度。

如果没有错误发生,bind()返回0。

否则返回值SOCKET_ERROR。

地址在建立套接字通信过程中起着重要作用,作为一个网络应用程序设计者对套接字地址结构必须有明确认识。

3)建立套接字连接──connect()与accept()

这两个系统调用用于完成一个完整相关的建立,其中connect()用于建立连接。

无连接的套接字进程也可以调用connect(),但这时在进程之间没有实际的报文交换,调用将从本地操作系统直接返回。

这样做的优点是程序员不必为每一数据指定目的地址,而且如果收到的一个数据报,其目的端口未与任何套接字建立“连接”,便能判断该端口不可操作。

而accept()用于使服务器等待来自某客户进程的实际连接。

connect()的调用格式如下:

intconnect(SOCKETs,conststructsockaddrFAR*name,intnamelen);

参数s是欲建立连接的本地套接字描述符。

参数name指出说明对方套接字地址结构的指针。

对方套接字地址长度由namelen说明。

如果没有错误发生,connect()返回0。

否则返回值SOCKET_ERROR。

在面向连接的协议中,该调用导致本地系统和外部系统之间连接实际建立。

由于地址族总被包含在套接字地址结构的前两个字节中,并通过socket()调用与某个协议族相关。

因此bind()和connect()无须协议作为参数。

accept()的调用格式如下:

SOCKETaccept(SOCKETs,structsockaddrFAR*addr,intFAR*addrlen);

参数s为本地套接字描述符,在用做accept()调用的参数前应该先调用过listen()。

addr指向客户方套接字地址结构的指针,用来接收连接实体的地址。

addr的确切格式由套接字创建时建立的地址族决定。

addrlen为客户方套接字地址的长度(字节数)。

如果没有错误发生,accept()返回一个SOCKET类型的值,表示接收到的套接字的描述符。

否则返回值INVALID_SOCKET。

accept()用于面向连接服务器。

参数addr和addrlen存放客户方的地址信息。

调用前,参数addr指向一个初始值为空的地址结构,而addrlen的初始值为0;调用accept()后,服务器等待从编号为s的套接字上接受客户连接请求,而连接请求是由客户方的connect()调用发出的。

当有连接请求到达时,accept()调用将请求连接队列上的第一个客户方套接字地址及长度放入addr和addrlen,并创建一个与s有相同特性的新套接字号。

新的套接字可用于处理服务器并发请求。

四个套接字系统调用,socket()、bind()、connect()、accept(),可以完成一个完全五元相关的建立。

socket()指定五元组中的协议元,它的用法与是否为客户或服务器、是否面向连接无关。

bind()指定五元组中的本地二元,即本地主机地址和端口号,其用法与是否面向连接有关:

在服务器方,无论是否面向连接,均要调用bind();在客户方,若采用面向连接,则可以不调用bind(),而通过connect()自动完成。

若采用无连接,客户方必须使用bind()以获得一个唯一的地址。

以上讨论仅对客户/服务器模式而言,实际上套接字的使用是非常灵活的,唯一需遵循的原则是进程通信之前,必须建立完整的相关。

监听连接──listen()

此调用用于面向连接服务器,表明它愿意接收连接。

listen()需在accept()之前调用,其调用格式如下:

intlisten(SOCKETs,intbacklog);

参数s标识一个本地已建立、尚未连接的套接字号,服务器愿意从它上面接收请求。

backlog表示请求连接队列的最大长度,用于限制排队请求的个数,目前允许的最大值为5。

如果没有错误发生,listen()返回0。

否则它返回SOCKET_ERROR。

listen()在执行调用过程中可为没有调用过bind()的套接字s完成所必须的连接,并建立长度为backlog的请求连接队列。

调用listen()是服务器接收一个连接请求的四个步骤中的第三步。

它在调用socket()分配一个流套接字,且调用bind()给s赋于一个名字之后调用,而且一定要在accept()之前调用。

数据传输──send()与recv()

当一个连接建立以后,就可以传输数据了。

常用的系统调用有send()和recv()。

send()调用用于在参数s指定的已连接的数据报或流套接字上发送输出数据,格式如下:

intsend(SOCKETs,constcharFAR*buf,intlen,intflags);

参数s为已连接的本地套接字描述符。

buf指向存有发送数据的缓冲区的指针,其长度由len指定。

flags指定传输控制方式,如是否发送带外数据等。

如果没有错误发生,send()返回总共发送的字节数。

否则它返回SOCKET_ERROR。

recv()调用用于在参数s指定的已连接的数据报或流套接字上接收输入数据,格式如下:

intrecv(SOCKETs,charFAR*buf,intlen,intflags);

参数s为已连接的套接字描述符。

buf指向接收输入数据缓冲区的指针,其长度由len指定。

flags指定传输控制方式,如是否接收带外数据等。

如果没有错误发生,recv()返回总共接收的字节数。

如果连接被关闭,返回0。

否则它返回SOCKET_ERROR。

输入/输出多路复用──select()

select()调用用来检测一个或多个套接字的状态。

对每一个套接字来说,这个调用可以请求读、写或错误状态方面的信息。

请求给定状态的套接字集合由一个fd_set结构指示。

在返回时,此结构被更新,以反映那些满足特定条件的套接字的子集,同时,select()调用返回满足条件的套接字的数目,其调用格式如下:

intselect(intnfds,fd_setFAR*readfds,fd_setFAR*writefds,fd_setFAR*exceptfds,conststructtimevalFAR*timeout);

参数nfds指明被检查的套接字描述符的值域,此变量一般被忽略。

参数readfds指向要做读检测的套接字描述符集合的指针,调用者希望从中读取数据。

参数writefds指向要做写检测的套接字描述符集合的指针。

exceptfds指向要检测是否出错的套接字描述符集合的指针。

timeout指向select()函数等待的最大时间,如果设为NULL则为阻塞操作。

select()返回包含在fd_set结构中已准备好的套接字描述符的总数目,或者是发生错误则返回SOCKET_ERROR。

关闭套接字──closesocket()

closesocket()关闭套接字s,并释放分配给该套接字的资源;如果s涉及一个打开的TCP连接,则该连接被释放。

closesocket()的调用格式如下:

BOOLclosesocket(SOCKETs);

参数s待关闭的套接字描述符。

如果没有错误发生,closesocket()返回0。

否则返回值SOCKET_ERROR。

(7)多路复用——select()

  功能:

用来检测一个或多个套接字状态。

  格式:

intPASCALFARselect(intnfds,fd_setFAR*readfds,fd_s

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

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1