网络编程技术教程课件

PPT
  • 阅读 130 次
  • 下载 0 次
  • 页数 49 页
  • 大小 320.512 KB
  • 2022-11-24 上传
  • 收藏
  • 违规举报
  • © 版权认领
下载文档25.00 元 加入VIP免费下载
此文档由【小橙橙】提供上传,收益归文档提供者,本网站只提供存储服务。若此文档侵犯了您的版权,欢迎进行违规举报版权认领
网络编程技术教程课件
可在后台配置第一页与第二页中间广告代码
网络编程技术教程课件
可在后台配置第二页与第三页中间广告代码
网络编程技术教程课件
可在后台配置第三页与第四页中间广告代码
网络编程技术教程课件
网络编程技术教程课件
还剩10页未读,继续阅读
【这是免费文档,您可以免费阅读】
/ 49
  • 收藏
  • 违规举报
  • © 版权认领
下载文档25.00 元 加入VIP免费下载
文本内容

【文档说明】网络编程技术教程课件.ppt,共(49)页,320.512 KB,由小橙橙上传

转载请保留链接:https://www.ichengzhen.cn/view-45654.html

以下为本文档部分文字说明:

1C#网络编程技术教程第六章TCP/UDP编程第6章TCP/UDP编程2学习目标•了解TCP和UDP。•掌握C#中面向TCP和UDP编程的主要类:TcpClient、TcpListener和UdpClient

。•掌握TcpClient、TcpListener和UdpClient的编程方法。•了解多播的原理,掌握基于UdpClient的多播编程方法。第6章TCP/UDP编程3本章内容6.1TCP/UDP概述6.2.NET中的TCP编程基础6.3基于T

CP的编程实例6.4.NET中的UDP编程基础6.5多播编程第6章TCP/UDP编程46.1TCP/UDP概述在TCP/IP协议族中,传输层主要包括TCP和UDP两种通信协议,它们以不同的方式实现两台主机中的不同应用程序之间

的数据传输,即数据的端到端传输。由于它们的实现方式不同,因此各有一套属于自己的端口号,且相互独立。可以采用如下五元组来描述两个应用进程之间的通信关联。(协议,信源机IP地址,信源应用进程端口,信宿机IP地址,信宿应用进程端口)即端到端之间的一

条通信连接就可以表示为上述五元组,这也是进行网络程序设计最基本的概念。其中,传输控制协议(TransmissionControlProtocol,TCP)提供一种面向连接的、可靠的数据传输服务,保证了端到端数据传输的

可靠性。也正因为这样,使TCP协议成为传输层最常用的协议,同时也是一个比较复杂的协议,其提供了传输层几乎所有的功能。因此和IP协议一样,成为了TCP/IP协议族中最重要的协议之一。其主要特点如下:(1)

向应用进程提供面向连接的服务,两个需要通过TCP协议进行数据传输的应用进程之间首先必须建立一个TCP连接,并且在数据传输完成后要释放连接。一般将请求连接的应用进程称为客户进程,而响应连接请求的应用进程称为服务器进程,即T

CP连接的建立采用的是一种客户机/服务器工作模型。(2)提供全双工数据传输服务,只要建立了TCP连接,就能在两个应用进程间进行双向的数据传输服务,但是这种传输只是端到端的传输,不支持广播和多播。第6章TCP/UDP编程56.1TCP/UDP概述(3)提供面向字节

流的服务,即TCP协议的数据传输是面向字节流的,两个建立了TCP连接的应用进程之间交换的是字节流。发送进程以字节流形式发送数据,接收进程也把数据作为字节流来接收。端到端之间不保留数据记录的边界,也就是说,在传输的层面上不存在数据记录的概念。用户数据报协

议(UserDatagramProtocol,UDP)是传输层的两个主要协议之一,相对TCP协议来说,UDP是一种非常简单的协议,在网络层的基础上实现了应用进程之间端到端的通信。与TCP协议不同,UDP协议是一种无连接的协议,数据在传输之前通信双方不需要建立连接。信宿在收到UDP数

据报之后也不需要给出任何应答报文。发送方发出的每一个UDP用户数据报都是独立的,都携带了完整的目的地址。每个数据报都可以被网络系统独立路由。因此从同一个信源发往同一个信宿的多个UDP报文可能选择不同的路径达到信宿,它们达到的先后顺序也可能不同于发送顺序。所

以,UDP协议提供的是一种无连接的、不可靠的数据传输方式,在数据传输过程中没有流量控制和确认机制,数据报可能会丢失、延迟、乱序到达信宿。UDP协议只是提供了利用校验和检查数据完整性的简单差错控制,属于一种尽力而为的数据传输方式。虽然UDP用户数据报只提供不可靠的传输方式,

但它具有其自身的一些特点:(1)UDP是一个无连接协议,传输数据之前信源和信宿不需要建立连接,因此不存在连接建立的时延。在信源端,UDP传送数据的速度仅仅受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在信宿端,UDP把每个数据报放在队列中,应用程序每次从队

列中读一个数据报。第6章TCP/UDP编程66.1TCP/UDP概述(2)由于传输数据不需要建立连接,也就不需要维护连接状态,包括收发状态等,这样一台服务机可同时向多个客户机传输相同的数据,例如实现多

播。(3)UDP数据报的首部很短,只有8字节,相对于TCP的20字节首部的开销要小很多。(4)吞吐量不受流量控制算法的调节,只受应用软件生成数据的速率、传输带宽、信源和信宿主机性能的限制。由于UDP具有这些特点,有许多应用

更适合使用UDP协议,如:(1)只需要简单数据交换的应用,例如DNS服务,它不需要复杂的可靠性保证机制,这样,利用UDP来传输数据既可以节省系统开销又提高了网络的传输效率。(2)不需要关心数据的差错控制和流量控制的应用。(3)实时性要求较高但可承受一定的数据错误

的应用,例如实时语音传输、实时视频通信等。(4)实现一对多数据发送的应用,例如广播和组播。第6章TCP/UDP编程76.2.NET中的TCP编程基础6.2.1TcpClient类TcpClient类为TCP网络服务提供客户端连接,它构建于Sock

et类之上,以提供较高级别的TCP服务,即提供了通过网络连接、发送和接收数据的简单方法。用于在同步阻止模式下通过网络来连接、发送和接收流数据。另外,通过与NetworkStream对象的关联,使得用户可以通过流操作方式实现对网络连接状态下数据的发送和接收

。TcpClient类的常见属性和方法分别见下表。属性描述Available获取网络接收缓冲区中可供读取的数据量Client获取或设置基础SocketConnected标识TcpClient的基础Socket是否已连接到远程主机NoDelay指定在发送或接收缓

冲区未满时,套接字是否将延迟发送或接收数据ReceiveBufferSize获取或设置接收缓冲区的大小ReceiveTimeout获取或设置在初始化一个读取操作以后TcpClient等待接收数据的时间量SendBu

fferSize获取或设置发送缓冲区的大小SendTimeout获取或设置TcpClient等待发送操作成功完成的时间量第6章TCP/UDP编程86.2.NET中的TCP编程基础6.2.1TcpClient类TcpClient构造函数BeginConnect开始一个对远程主机连接的异步请求

Close释放TcpClient实例,而不关闭基础连接Connect依据指定的主机名和端口号连接到TCP主机EndConnect异步接受传入的连接尝试GetStream返回用于发送和接收数据的NetworkStream实例第6章TCP/UDP编程96.2.N

ET中的TCP编程基础6.2.1TcpClient类通过TcpClient类实现与TCP主机的通信流程如图所示。1.创建TcpClient实例TcpClient类有4种构造函数的重载形式,分别对应4种创建实例的方法。(1)TcpClie

nt(),这种不带任何参数的构造函数将使用本机默认的IP地址并将使用默认的通信端口号0。当然,如果本机不止一个IP地址时将无法选择使用。(2)TcpClient(AddressFamily),使用指定的地址族初始化TcpClient类的新实例。(3

)TcpClient(IPEndPoint),即使用本机IPEndPoint创建TcpClient的实例。其中IPEndPoint将网络端点表示为IP地址和端口号,用于指定在建立远程主机连接时所使用的本地网络接口IP地址和端口号。(4)Tc

pClient(String,Int32),初始化TcpClient类的新实例并连接到指定主机上的指定端口。因此,在TcpClient的构造函数中,如果没有指定远程主机名和端口号,它只是用来实例化Tcp

Client,同时实现与本地IP地址和Port端口的绑定。第6章TCP/UDP编程106.2.NET中的TCP编程基础6.2.1TcpClient类2.与远程主机建立连接如果在TcpClient的实例化过程中没有实现与远程主机的连

接,则可以通过Connect方法来实现与指定远程主机的连接。Connect方法使用指定的主机名和端口号将客户端连接到远程主机,其使用方法如下。(1)Connect(IPEndPoint),使用指定的远程网络终结点将客户端连接到远程TCP主机。(2)Con

nect(IPAddress),使用指定的IP地址和端口号将客户端连接到远程TCP主机。(3)Connect(IPAddress[],Int32),使用指定的IP地址和端口号将客户端连接到远程TCP主机。(4)Connect(String,Int32),使

用指定的主机名和端口号将客户端连接到指定主机上的指定端口。如下代码段描述了TcpClient实例的创建以及与指定远程主机的连接过程。m_client=newTcpClient();m_client.Connect(m_servername,m_port);第6

章TCP/UDP编程116.2.NET中的TCP编程基础6.2.1TcpClient类3.利用NetworkStream实例发送和接收数据TcpClient类创建在Socket之上,提供了更高层次的TCP服务抽象,特别是在网络数据的发送和接收方面,TcpClient使用标准的Stream流处理

技术,通过使用NetworkStream实例的读写操作来实现网络数据的接收和发送,因此更加方便直观。但NetworkStream与普通流Stream有所不同,NetworkStream没有当前位置的概念,不支持查找和对数据流

的随机访问。该方法首先通过TcpClient.GetStream来返回NetworkStream实例,进而利用所获取的NetworkStream实例的读写方法Write和Read来发送和接收数据,其实现代码如下所示。rs=newStreamReader(m_client.GetSt

ream());//获取接收数据的网络流实例ws=m_client.GetStream();//获取发送数据的网络流实例m_returnData=rs.ReadLine();//接收网络数据Console.WriteLine

(m_returnData);ws.Write(data,0,data.Length);//向网络发送数据4.关闭TCP套接字在与服务器完成通信后,应该调用Close()方法释放所有的资源。m_client.Close();第6章TCP/UDP编程126

.2.NET中的TCP编程基础6.2.2TcpListener类TcpClient类实现了客户端编程抽象,因此构建客户端网络应用程序便可以直接使用TcpClient取代Socket,更加方便易用。同样,对于服务器端应用程序的构建,C#提供了TcpListe

ner类。该类也是构建于Socket之上,提供了更高抽象级别的TCP服务,使得程序员能更方便地编写服务器端应用程序。TcpListener类的常见属性和方法分别如表6.3、表6.4所示。名称描述ExclusiveAddressUse获

取或设置一个布尔值,以指定当前TcpListener是否只允许一个基础套接字来侦听特定端口LocalEndpoint获取当前TcpListener的基础IPEndPoint实例,此对象包含关于本地网络接口的IP地址和端口号信息Active指明TcpList

ener是否正在侦听连接请求(受保护方法)Server获取基础网络Socket实例第6章TCP/UDP编程136.2.NET中的TCP编程基础6.2.2TcpListener类名称描述AcceptSocket接受挂起的连接请求

,并返回一个Socket实例用来与客户进行通信AcceptTcpClient接受挂起的连接请求,并返回一个TcpClient实例用来与客户进行通信BeginAcceptSocket开始一个异步操作来接受一

个传入的连接尝试BeginAcceptTcpClient开始一个异步操作来接受一个传入的连接尝试EndAcceptSocket异步接受传入的连接尝试,并创建新的Socket来处理远程主机通信EndAcceptTcpClient异步接受传入的连接尝试,并创建新的TcpCli

ent来处理远程主机通信Pending确定是否有挂起的连接请求Start开始侦听客户端的连接请求Stop关闭侦听器第6章TCP/UDP编程146.2.NET中的TCP编程基础6.2.2TcpListener类通常情况下,服务器端应用程序在

启动时将首先绑定本地网络接口的IP地址和端口号,然后进入侦听客户请求的状态,以便于客户端应用程序提出显式请求。一旦侦听到有客户端应用程序请求连接侦听端口,服务器端应用将接受请求,并建立一个负责与客户端应用程序通信的信道,即通过创建连接套接字与客户端应用程序建立连接,由

连接套接字完成与客户端应用程序的数据传送操作,服务器端应用程序继续侦听更多的客户端连接请求。TcpListener通过实例创建过程完成与本地网络接口的绑定,并由所创建的实例调用Start方法启动侦听;当侦听到客户端应用程序的连接请求后,根据

客户端应用程序的不同请求方式,可以通过AcceptTcpClient方法接受传入的连接请求并创建TcpClient实例以处理请求,或者通过AcceptSocket方法接受传入的连接请求并创建Socket实例以处理请求,并由所创建的TcpClient实例或Socket实例完成与客户端应用程序的网络数

据传输。最后,需要使用Stop关闭用于侦听传入连接的Socket,同时也必须关闭从AcceptSocket或AcceptTcpClient返回的任何实例,以释放相关资源。其实现流程如右图所示。第6章TCP/UDP编程156

.2.NET中的TCP编程基础6.2.2TcpListener类1.创建TcpListener实例TcpListener类提供了3种构造函数的重载形式来创建TcpListener实例。(1)TcpListener(po

rt);//指定本机端口(2)publicTcpListener(IPEndPoint)//指定本机终结点(3)publicTcpListener(IPAddress,port)//指定本机IP地址及端口分别根据指定的侦听端口、I

PEndPoint对象(包含了IP地址和端口号)、IPAddress对象和端口号来创建TcpListener实例,并且实现与默认端口或指定IP地址和端口的绑定,如:m_host=IPAddress.Parse(m_serverIP);m_Listener=newTcpListener(m_ho

st,m_port);2.侦听创建TcpListener实例后,便可以调用Start方法启动侦听,即该方法将调用TcpListener实例的基础Socket上的Listen方法,开始侦听客户的连接请求,如:m_Listener.Start();3.接收连接请求当侦听到有客户连接请求时,可以

使用AcceptSocket或AcceptTcpClient接收任何当前在队列中挂起的连接请求。这两种方法分别返回一个Socket或TcpClient实例以接受客户的连接请求,如:TcpClientm_client=m_Listener.A

cceptTcpClient();通过返回的Socket或TcpClient实例来实现与提出连接请求的客户的单独网络数据传输。第6章TCP/UDP编程166.2.NET中的TCP编程基础6.2.2TcpListener类4.收发数

据如果接收连接请求时返回的是Socket实例,则可以用Send和Receive方法实现与客户的通信。如果返回的是TcpClient实例,则可以通过对NetworkStream的读写来实现与客户的数据通信。由于服务器可以同时与多个客户建立

连接并进行数据通信,因此往往会引入多线程技术,为每个客户的连接建立一个线程,在该线程中实现与客户的数据通信。如下代码所示。//为每个客户连接创建并启动一个线程TcpClientm_client=m_Listener.AcceptTcpClient

();ClientHandlem_handle=newClientHandle();m_handle.ClientSocket=m_client;Threadm_clientthread=newThread(newThrea

dStart(m_handle.ResponseClient));m_clientthread.Start();第6章TCP/UDP编程176.2.NET中的TCP编程基础6.2.2TcpListener类//线程处理代码publicvoidResponseClient(

){if(m_clientsocket!=null){StreamReaderrs=newStreamReader(m_clientsocket.GetStream());NetworkStreamws=m_clientsocket.GetStream();……while(true)

{//接收信息m_returnData=rs.ReadLine();……//回送信息ws.Write(data,0,data.Length);……}m_clientsocket.Close();}}5.关闭连接与客户程序通信完成之后,最后一步是停

止侦听套接字,此时可以调用TcpListener的Stop方法来实现。第6章TCP/UDP编程186.3基于TCP的编程实例为了综合应用TcpListener和TcpClient实现网络应用程序的设计,本节设计了一个简单的询问时间和回应程序,即客户端程序可以利用GE

TDATE命令询问服务器的当前时间,而对于除命令以外的数据,服务器则原样返回给客户端程序。客户端程序和服务器程序的交互流程如图6.3所示。在实现中,为了能使服务器更好地响应多个客户的请求,服务器程序的设计采用了多线程技术,

针对每个客户创建并启动一个线程与之通信。整个系统的类图如图6.4所示。图6.3客户端程序和服务器程序交互流程图图6.4系统类图第6章TCP/UDP编程196.3基于TCP的编程实例6.3.1服务器端编程服务器程序的实现主要是基于TcpListener、TcpClient和多线程技术,

利用TcpListener实例进行客户连接的侦听和接受客户连接请求,而通过多线程技术为每个客户连接创建一个处理线程,完成与客户程序的通信。服务器程序运行所需的本机网络接口IP和侦听端口号都利用命令行参数获取。程序如下:usingSystem;usingSys

tem.Net;usingSystem.IO;usingSystem.Net.Sockets;usingSystem.Threading;usingSystem.Collections;usingSystem.Text;namespaceServer{//客户连接处理,用来接收和发送网

络数据classClientHandle{privatestringm_usename;privateTcpClientm_clientsocket=null;//TcpClient实例privatestringm_returnData,m_s

endData;//接收和发送数据byte[]data;//中间变量publicTcpClientClientSocket{//属性get{returnm_clientsocket;}set{m_client

socket=value;}}byte[]EncodingASCII(stringbuf)//将数据转换为ASCII{byte[]data=Encoding.ASCII.GetBytes(buf+"\r\n");returndata;}第6章TCP/UDP编程206.3

基于TCP的编程实例6.3.1服务器端编程publicvoidResponseClient(){if(m_clientsocket!=null){StreamReaderrs=newStreamReader(m_c

lientsocket.GetStream());NetworkStreamws=m_clientsocket.GetStream();//获取用户名m_returnData=rs.ReadLine();m_usename=m_returnData;//保留用户名m_sendData="Welc

ome"+m_returnData+"toServer";Console.WriteLine(m_sendData);//显示信息//回送欢迎信息data=EncodingASCII(m_sendData);ws.Writ

e(data,0,data.Length);while(true){//接收信息m_returnData=rs.ReadLine();//解释所接收的信息if(m_returnData.IndexOf("QUIT

")>-1){Console.WriteLine(m_usename+"hasquited!");//显示退出信息break;}elseif(m_returnData.IndexOf("GETDATA")>-1){m_sendData=DateTime.Now.ToString();//回送

当前时间}else{m_sendData="-->"+m_returnData;//回送所接收的信息}//回送信息data=EncodingASCII(m_sendData);ws.Write(data,0,data.Leng

th);}m_clientsocket.Close();}}}第6章TCP/UDP编程216.3基于TCP的编程实例6.3.1服务器端编程classServer{staticvoidMain(string[]args){stringm_serverIP="172.0.0.1";intm_po

rt=5555;boolrt=false;TcpListenerm_Listener=null;IPAddressm_host;if(args.Length<2)Console.WriteLine("Usage:ServerSe

rverIPPort");else{try{m_serverIP=args[0].ToString();m_port=int.Parse(args[1].ToString());rt=true;}catch(Exception

e){Console.WriteLine("ParametreError:"+e.Message);}}第6章TCP/UDP编程226.3基于TCP的编程实例6.3.1服务器端编程if(rt){try{m_host=IPAddress.Pars

e(m_serverIP);m_Listener=newTcpListener(m_host,m_port);m_Listener.Start();Console.WriteLine("Startingtolisten....");while(true){TcpClientm_client=m_

Listener.AcceptTcpClient();ClientHandlem_handle=newClientHandle();m_handle.ClientSocket=m_client;Threadm_clientthread=n

ewThread(newThreadStart(m_handle.ResponseClient));m_clientthread.Start();}m_Listener.Stop();}catch(Exceptione){Cons

ole.WriteLine("Exception:"+e.Message);}}}}}第6章TCP/UDP编程236.3基于TCP的编程实例6.3.2客户端编程客户程序负责向服务器发送询问时间命令GETDATE、退出命令QUIT和其他数据信息。它运行所需的参数,包括用

户名、服务器地址和服务器侦听端口号都是通过命令行参数获取。实现过程如代码实例6.2所示。usingSystem;usingSystem.Net;usingSystem.IO;usingSystem.Net.Sockets;usingSystem.Text;namespac

eClient{//客户类classClient{staticbyte[]EncodingASCII(stringbuf)//将数据转换为ASCII{byte[]data=Encoding.ASCII.GetBytes(buf+"\r\n");returndata;}stati

cvoidMain(string[]args){stringm_servername="127.0.0.1",m_usename="NoName";intm_port=5555;TcpClientm_client;bo

olrt=false;stringm_sendData,m_returnData;byte[]data;StreamReaderrs;NetworkStreamws;第6章TCP/UDP编程246.3基于TCP的编程实例6.3.2客户端编程if(args.Length<3)Consol

e.WriteLine("Usage:ClientUsenameServerNamePort");else{try//获取命令行参数{m_usename=args[0].ToString();m_servername=args[1].ToString();m_port=in

t.Parse(args[2].ToString());rt=true;}catch(Exceptione){Console.WriteLine("ParametreError:"+e.Message);}}if(rt){try{//创建TcpClient实例,并向服务器

提出连接请求m_client=newTcpClient();m_client.Connect(m_servername,m_port);rs=newStreamReader(m_client.GetStream());ws=m_client.GetStream();//发送用户名m_se

ndData=m_usename;data=EncodingASCII(m_sendData);ws.Write(data,0,data.Length);第6章TCP/UDP编程256.3基于TCP的编程实例6.3.2客户端编程while(true){//获取返回信息并显示m_returnData

=rs.ReadLine();Console.WriteLine(m_returnData);//发送命令或其他信息Console.WriteLine("Inputdata[GETDATE|QUIT|Other]:");m_sendData=Con

sole.ReadLine();if(m_sendData.IndexOf("QUIT")>-1)//退出{m_sendData="QUIT";}elseif(m_sendData.IndexOf("GETDATE

")>-1)//询问时间命令{m_sendData="GETDATE";}data=EncodingASCII(m_sendData);ws.Write(data,0,data.Length);//发送数据if(m_sendData.IndexOf("QUIT")>-1)bre

ak;}m_client.Close();}catch(Exceptione){Console.WriteLine("Exception:"+e.Message);}}}}}第6章TCP/UDP编程266.4.NET中的UDP编程基础在.NET中,基于UD

P协议的网络程序设计可以通过以下4种方法来实现。WinsockAPIWinsock非托管APISocket类UdpClient类前面两种都是直接利用操作系统或第三方提供的网络编程API实现,这要求编程人员必须对网络编

程的底层知识有较好的了解。而Socket类实质上是WinsockAPI的一个包装器,使用Socket类进行网络程序设计与直接使用WinsockAPI类似。UdpClient类是基于Socket类的较高级别抽象,提供了较高级别的UDP服务。较前面三种方法具有直观易用等优势。因此,在

.NET环境中基于UDP协议的网络程序设计可以直接用UdpClient类。6.4.1UdpClient类与TcpClient和TcpListener类似,UdpClient也是构建于Socket类之上,提供了更高层次的UDP服务抽象,用于在阻止同步模式下

发送和接收无连接UDP数据报,使用简单直观。UdpClient类的常见方法和属性分别如表6.5、表6.6所示。第6章TCP/UDP编程276.4.NET中的UDP编程基础BeginReceive从远程主机异步接收数据报BeginSend将数据报异

步发送到远程主机Close关闭UDP连接Connect指定发送数据的默认远程主机DropMulticastGroup退出多播组EndReceive结束挂起的异步接收EndSend结束挂起的异步发送JoinMulticastGro

up将当前的UdpClient实例添加到多播组Receive接收已由远程主机发送的UDP数据报,同时返回远程主机信息Send将UDP数据报发送到远程主机6.4.1UdpClient类Available获取从网络接收的

可读取的数Client获取或设置基础网络SocketDontFragment获取或设置指定UdpClient实例协议数据报进行分段的标志EnableBroadcast获取或设置指定UdpClient实例或

接收广播数据包的标志ExclusiveAddressUse获取或设置指定UdpClient是否户端使用端口的标志MulticastLoopback获取或设置是否将输出多播数送应用程序的标志Ttl获取或设置指定由UdpClient发据包的生存时间TTL的值第6章TCP/UDP编程286.4.NE

T中的UDP编程基础6.4.1UdpClient类基于UdpClient的网络应用编程首先需要创建一个UdpClient类实例,接着通过调用其Connect方法连接到远程主机。当然,这两步也可以直接由指

定远程主机名和端口号的UdpClient类构造函数完成。然后便可以利用Send和Receive方法来发送和接收数据。最后调用Close方法关闭UDP连接,并释放相关资源。其实现流程如图6.5所示。图6.5基于UdpClient的编程流程第6章TCP/UDP编程296.4.

NET中的UDP编程基础6.4.1UdpClient类1.创建UdpClient实例UdpClient提供了3种构造函数的重载方式来创建UdpClient实例,根据传入参数的不同完成不同的创建形式,如下所述

。UdpClient(),以缺省方式初始化UdpClient的新实例,IP地址和端口号皆由系统自动指定。UdpClient(AddressFamily),以指定的地址族初始化UdpClient的新实例。UdpClient(Int32),以指定的端口号初始化UdpClient

的新实例。UdpClient(IPEndPoint),以指定的本地终结点初始化UdpClient类的新实例。UdpClient(Int32,AddressFamily),以指定的端口号和地址族初始化UdpClient的新实例。UdpClient(Stri

ng,Int32),以指定的远程主机名和端口号初始化UdpClient的新实例,并建立默认远程主机。其中,UdpClient(String,Int32)重载形式在完成UdpClient实例初始化的同时也完成了远程主机连接信息

的指定。2.指定连接信息因为UDP是无连接传输协议,所以不需要在发送和接收数据前建立远程主机连接。但可以选择使用下面两种方法之一来指定默认远程主机:使用远程主机名和端口号作为参数创建UdpClient类的实例。创建

UdpClient类的实例,然后调用Connect方法。第6章TCP/UDP编程306.4.NET中的UDP编程基础6.4.1UdpClient类如果在创建UdpClient实例时没有指定远程主机信息,那么可以在发送数据前通过UdpClient的Connect方法先指定远程主机

的地址和端口号,即指定连接信息。但是如果只需要接收数据,则不需要进行指定连接的操作。对于连接信息的指定,主要包括三种方式,即直接在UdpClient的构造函数中指定,通过调用Connect方法指定和直接在Send方法中指定。而Connect方法又有

三种重载形式,如下:UdpClient.Connect(IPEndPoint),使用指定的远程主机信息建立默认远程主机。UdpClient.Connect(IPAddress,Int32),使用指定的IP地址和端口号建立默认远程主机。UdpCli

ent.Connect(String,Int32),使用指定的主机名和端口号建立默认远程主机。下面的代码段实现了UdpClient实例创建和连接信息指定操作。IPAddressm_ipA=IPAddress.Parse(m_hostIP);m_EndPoint=newIPEndPoint(m

_ipA,m_port);m_client=newUdpClient();//创建UdpClient实例m_client.Connect(m_EndPoint);//指定连接信息3.数据发送和接收UdpClie

nt实例创建后便可以进行数据发送和接收操作,如图6.5所示。UdpClient中提供了Send方法来完成数据发送操作,其重载形式有如下三种。第6章TCP/UDP编程316.4.NET中的UDP编程基础6.4.1UdpClient类UdpClien

t.Send(Byte[],Int32),将UDP数据报发送到默认的远程主机。UdpClient.Send(Byte[],Int32,IPEndPoint),将UDP数据报发送到位于指定远程终结点的主机。UdpClient.Send(Byte[],Int3

2,String,Int32),将UDP数据报发送到指定的远程主机上的指定端口。因此,数据发送操作既可以在先指定连接信息的情况下给出发送数据及其长度进行发送,也可以由Send方法来指定远程主机的端口信息以及发送数据和长度进行发送。如下所示。m_client.Send(d

ata,data.Length);//在指定了连接信息后,直接给出数据及其长度进行发送在UdpClient中提供了Receive方法来完成数据的接收操作,其申明形式如下:byte[]Receive(refIPEndPointremoteEP)。在接收缓冲区没有数据时,Rece

ive方法将阻止,直到数据报从远程主机到达为止。如果数据可用,则Receive方法将读取接收缓冲区的第一个数据报,并将数据部分作为字节数组返回。在返回数据的同时使用发送方的IPAddress和端口号来填充remoteEP参数。如果在Co

nnect方法中指定了默认的远程主机,则Receive方法将只接收来自该主机的数据报,其他所有数据报将被丢弃。因此,如果需要接收多播数据报,则在调用Receive方法之前不能利用Connect方法来指定连接信息,并且必须使用多播端口号来创建用于接收

数据报的UdpClient。下面程序段实现了对远程主机所发送信息的接收操作。第6章TCP/UDP编程326.4.NET中的UDP编程基础6.4.1UdpClient类IPEndPointm_EndPoint;byte[]data;data=

m_client.Receive(refm_EndPoint);//接收数据,同时远程主机信息返回给m_EndPoint4.关闭连接使用UdpClient的最后一步是关闭连接,可以直接调用UdpClient的Close方法来实现。6.4.2基于UdpClient类的编程实例在本节中设计了一个简

单的群组讨论工具,即参加讨论者可以利用UDPClient客户端程序加入讨论群组,也可以随时退出群组。当参加者加入讨论群组后,便可以向该群组发表自己的意见,服务器程序UDPServer会将任何一位参加者所发表的意见转发给群组中的

各位参加者,如图6.6所示。在实现中,系统设计了三个类,其中客户端程序包括UDPClient类,服务器程序包括UDPServer类,而UDPComm类中实现了客户端程序和服务器程序所需要的共性操作。整个系统的类图如图6.7所示。UDPComm、UDPClient和UD

PServer类的详细实现分别如代码实例6.3、代码实例6.4和代码实例6.5所示。第6章TCP/UDP编程336.4.NET中的UDP编程基础6.4.1UdpClient类图6.6客户端程序和服务器程序交互流程图6.7系统

类图第6章TCP/UDP编程346.4.NET中的UDP编程基础6.4.1UdpClient类代码实例6.3UDPComm类实现usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namesp

aceUDPComm{publicclassUDPComm{publicstaticbyte[]EncodingASCII(stringbuf)//编码{byte[]data=Encoding.ASCII.GetBy

tes(buf+"\r\n");returndata;}publicstaticstringDecodingASCII(byte[]buf)//解码{stringst=Encoding.ASCII.GetString(

buf);returnst;}}}第6章TCP/UDP编程356.4.NET中的UDP编程基础6.4.1UdpClient类代码实例6.4UDPClient类实现usingSystem;usingSystem.Collections;usingS

ystem.Net;usingSystem.Net.Sockets;usingSystem.Collections.Generic;usingSystem.Text;usingUDPComm;namespaceUDPClie

nt{classUDPClient{staticvoidMain(string[]args){stringm_hostIP="127.0.0.1";intm_port=6666;UdpClientm_clie

nt;boolrt=false;byte[]data;stringm_SendData,m_ReturnData;IPEndPointm_EndPoint;//从命令行提取服务器地址和侦听端口if(args.Length<2){

Console.WriteLine("Usage:UDPClienthostIPport");}else{m_hostIP=args[0].ToString();m_port=int.Parse(args

[1].ToString());rt=true;}第6章TCP/UDP编程366.4.NET中的UDP编程基础6.4.1UdpClient类if(rt){IPAddressm_ipA=IPAddress.

Parse(m_hostIP);m_EndPoint=newIPEndPoint(m_ipA,m_port);m_client=newUdpClient();m_client.Connect(m_EndPoint);while(true){Console.WriteLine("Input[A

DD|DEL|REF|QUIT|Message]:");m_SendData=Console.ReadLine();if(m_SendData.IndexOf("QUIT")>-1)//退出m_SendData="DEL";if(m_Se

ndData.IndexOf("REF")<=-1)//刷新显示{data=UDPComm.UDPComm.EncodingASCII(m_SendData);m_client.Send(data,data.Length);}if(m_Send

Data.IndexOf("QUIT")>-1)break;data=m_client.Receive(refm_EndPoint);//接收数据m_ReturnData=UDPComm.UDPComm.DecodingASCII(data);Console.WriteLi

ne(m_ReturnData);}//退出Console.WriteLine("Byte!");m_client.Close();}}}}第6章TCP/UDP编程376.4.NET中的UDP编程基础6.4.1UdpClien

t类代码实例6.5UDPServer类实现usingSystem;usingSystem.Collections;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.

Collections.Generic;usingSystem.Text;usingUDPComm;namespaceUDPServer{classUDPServer{staticUdpClientm_server;staticArrayListmbli

st;staticvoidAddMember(IPEndPointrep)//加入组{mblist.Add(rep);byte[]data=UDPComm.UDPComm.EncodingASCII("OK");m_server.

Send(data,data.Length,rep);}staticvoidDelMember(IPEndPointrep)//离开组{mblist.Remove(rep);byte[]data=UDPComm.UDPComm.EncodingASCII("OK");m_server.Send(

data,data.Length,rep);}staticvoidSendToMember(stringbuf)//组内转发数据{foreach(IPEndPointmbinmblist){byte[]data=UDPComm.UDPComm.EncodingA

SCII(buf);m_server.Send(data,data.Length,mb);}}第6章TCP/UDP编程386.4.NET中的UDP编程基础6.4.1UdpClient类staticvoidMain(string[]args){stringm_h

ostIP="127.0.0.1";intm_port=6666;IPEndPointm_EndPoint;ArrayListmemberlist=newArrayList();boolrt=false;byte[]data;string

m_ReturnData;//从命令行提取主机IP和端口if(args.Length<2){Console.WriteLine("Usage:UDPServerhostIPport");}else{m_hostIP=args[0].ToString();

m_port=int.Parse(args[1].ToString());rt=true;}if(rt){mblist=newArrayList();//组成员列表IPAddressm_ipA=IPAddress.Parse(m_hostIP

);m_EndPoint=newIPEndPoint(m_ipA,m_port);m_server=newUdpClient(m_EndPoint);Console.WriteLine("Readyfor

Connect......");第6章TCP/UDP编程396.4.NET中的UDP编程基础6.4.1UdpClient类while(true){data=m_server.Receive(refm_End

Point);//接收数据m_ReturnData=UDPComm.UDPComm.DecodingASCII(data);if(m_ReturnData.IndexOf("ADD")>-1)//加入组{AddMember(m_EndPoint);Console.Write

Line(m_EndPoint.ToString()+"hasaddedtogroup!");}elseif(m_ReturnData.IndexOf("DEL")>-1)//退出组{DelMember(m_EndPo

int);Console.WriteLine(m_EndPoint.ToString()+"hasdeletedfromgroup!");}else{if(mblist.Contains(m_EndPoin

t))//转发数据{SendToMember(m_ReturnData+"["+m_EndPoint.ToString()+"]");Console.WriteLine(m_ReturnData+"["+m_EndPoint.ToString()+"]"+"hasre

sentedtomembers!");}}}m_server.Close();}}}}第6章TCP/UDP编程406.5多播编程6.5.1多播概念近年来,随着因特网的迅速普及和发展,在因特网上产生了许多新的应用,

其中不少是基于宽带的多媒体应用,例如网络视频会议、网络音频/视频广播、视频点播、股市行情发布、多媒体远程教育、协同计算、远程会诊等。采用单播技术构建的传统网络已经无法满足这些新兴宽带网络应用在带宽和网络服务质量方面的要求,常常会带来网络延时、数据丢失等问题。为此,人们提出了多种解决方案

,例如增加互联带宽、引入QoS机制等。比较而言,IP多播技术有其独特的优越性。在多播网络中,即使用户数量成倍增长,主干带宽也不需要随之增加。简单来说,成百上千的多播应用用户和一个多播应用用户消耗的骨干网带宽是一样的,从而最

大限度地解决目前宽带应用对带宽和网络服务质量的要求。正因为如何,IP多播技术得到了迅速发展。多播是一种允许一个或多个发送者(多播源)将单一的数据包同时发送到多个接收者的网络技术。多播源把数据包发送到特定多播组,只有属于该多播组的成员才能接收到数据包,并且组成多播组的成员不限于在同一个

网络。因特网上的主机可以通过网际组管理协议(IGMP)加入某个多播组中,也可以动态离开该组,相关路由器将跟踪这种关系并形成一条到达多播组中每个成员的无回路路径,以便对多播成员实现有效管理,这些路由器不妨称其为

多播路由器。一旦多播数据包传递到某多播路由器,它将根据多播组的组成信息将该数据报转发到每一个多播成员,如图6.8所示。因此,多播可以大大地节省网络带宽,无论有多少个目标地址,在整个网络的任何一条链路上只传送单一的数据包。第6章TCP/UDP编程41

6.5多播编程6.5.1多播概念一个多播组由若干个主机构成,当某源主机要将数据发送给某个多播组上的所有主机时,首先需要构造一个能够标识该多播组的IP数据报,然后以尽力而为方式转发给对应多播组中的各个主机。为了标识多播组,在TCP/IP中引入了IP多播地址,每个多播组

都需要一个IP多播地址来标识。在TCP/IP协议族中,IP地址方案专门为多播划出了一个地址范围。例如IPv4中的D类地址,其范围是224.0.0.0~239.255.255.255,并将D类地址划分为局部

链接多播地址、预留多播地址和管理权限多播地址,如表6.7所示。图6.8多播工作示意图表6.7D类地址分配类别地址范围描述局部链接地址224.0.0.0~224.0.0.255用于局域网,路由器不转发属于此范围的I

P包预留多播地址224.0.1.0~238.255.255.255用于全球范围或网络协议管理权限地址239.0.0.0~239.255.255.255组织内部使用,用于限制多播范围第6章TCP/UDP编程426.5多播编程6.5.1多播概念为了更好地管理多播组中的成员,TCP/I

P中引入了网际组管理协议(InternetGroupManagementProtocol,IGMP),用于在多播路由器和主机之间进行群组关系的管理。该协议运行于主机和与主机直接相连的多播路由器之间。主机通过此协议告诉本地路由器

希望加入某个特定多播组的信息,同时路由器通过此协议周期性地查询局域网内某个已知组的成员是否处于活动状态(即该局域网是否仍有属于某个多播组的成员),实现所连网络组成员关系的收集与维护。在支持多播的网络中,多播群组管理所需要的数据主要存放在路由器中。每个支持多播的路由器都有一张多播地址表,其中

每个多播地址对应一个多播群组,而且一个多播群组至少包含本地网络上的一个成员。多播组是基于进程创建的,每个进程在主机的给定接口上可以加入一个多播组,也可以离开其先前加入的多播组。多播路由器负责把多播数据包传递给某个多播群组中的各个成员。如果一个物理网络上存在多个支持多

播的路由器,这些路由器上的多播地址表肯定是互不相同的。在因特网中,如何通过多播路由器来管理多播群组成员呢?IGMP提供三种操作方式来实现群组管理。第6章TCP/UDP编程436.5多播编程6.5.1多播概念1.加入多播组主机和路由器都可以加入

一个多播组。当某个主机中的一个进程申请加入一个多播组时,主机将发送一个成员关系报告报文到它所在的IP子网的多播路由器;路由器接收到该申请后将检查它的群组成员关系表,看该主机是否已经在群组中;如果该主机不在群组关系表中(即第一次申请),同时将自己的IP模块做相应的准备,以便

开始接收来自该多播组的数据。如果这台主机是它所在的IP子网中第一台加入该多播组的主机,则多播路由器将通过路由信息的交换加入多播分布树。2.退出多播组当主机发现在一个特定的多播组中已经没有进程时,就发送退出报告。多播路由器收到退

出报告后,并不立即删除这个群组,而是针对该群组发送查询报文。当在指定的时间内没有收到相关主机(和路由器)对该群组的成员关系报告时,就意味着在本网络上已经没有该群组成员,此时,多播路由器将删除该群组。否则继续保留该群组。3.查询成员关系由于多播组中的成员关系是动态变化的,并且有些变化是由于异常事

件而引起的,例如某个群组的某台成员主机因异常而关机,此时多播路由器将永远接收不到其退出报告。为了实时掌握群组的成员组成,IGMP提供了一种机制来监控某个网络上的所有主机和路由器,以便确定群组和主机或路由器之间的关系。第6章TCP/UDP编程446.5多播编程

6.5.2.NET中多播编程基础在.NET中,对多播编程没有特殊的类一级的支持,由于多播只支持UDP传输协议,因此只需要使用UdpClient类就可以实现多播数据的发送和接收。1.多播数据的发送对于多播数据的发送

,与普通的基于UDP协议的数据传输不同的是,必须使用一个多播地址,多播地址的范围从224.0.0.0~239.255.255.255。如下代码可以实现多播数据的发送。stringm_groupIP="235.5.6.1

1";//多播地址intm_port=7777;intm_ttl=2;UdpClientm_client;IPAddressm_ipA=IPAddress.Parse(m_groupIP);m_EndPoint=newIPE

ndPoint(m_ipA,m_port);m_client=newUdpClient();m_client.Send(data,data.Length,m_EndPoint);//多播数据发送2.多播数据的接收对于需要接收多播

数据的客户程序,首先必须加入多播组。在UdpClient类中提供了JoinMulticastGroup方法来实现加入多播组的操作。调用JoinMulticastGroup方法后,基础Socket将IGMP数

据包发送到路由器,请求成为多播组成员。如果指定的地址在多播地址范围之外,或者所请求的路由器不支持多播,则UdpClient类将引发SocketException异常。JoinMulticastGroup方法提供了四种重载形式,如下所

示。第6章TCP/UDP编程456.5多播编程(1)JoinMulticastGroup(IPAddress),根据指定的IP地址将UdpClient添加到多播组。(2)JoinMulticastGroup(Int32,

IPAddress),将UdpClient添加到多播组,其中第一个参数用来标识相同链接上的硬件接口。(3)JoinMulticastGroup(IPAddress,Int32),将指定的生存时间(TTL)与UdpClient一起添加到多播组。(4)JoinMulticastGroup(I

PAddress,IPAddress),将UdpClient添加到多播组,其中参数一为多播地址,参数二为本地地址。当客户程序需要离开多播组时可以使用UdpClient类中的DropMulticastGroup方法。DropMulticastGr

oup方法从指定多播组中收回UdpClient实例。调用DropMulticastGroup方法后,基础Socket将IGMP包发送到路由器,从多播组删除该应用。UdpClient从多播组中收回之后,将不能再接收发送到该组的

数据报。DropMulticastGroup方法提供了两种重载形式,如下所示。(1)DropMulticastGroup(IPAddress),从指定的多播组中退出。(2)DropMulticastGroup(IPAddress,Int32

),从指定的多播组中退出,其中参数二为要退出多播组的本地地址。如下代码段根据条件实现了加入多播组和离开多播组的操作。if(m_SendData.IndexOf("ADD")>-1)//加入多播组{m_client.JoinMulticastGroup(m_ipA,

m_ttl);}elseif(m_SendData.IndexOf("DEL")>-1)//退出多播组{m_client.DropMulticastGroup(m_ipA);}6.5.2.NET中多播编程基础第6章TCP/UDP编程466.5多播编程6.5.3基于UdpClien

t的多播实例在本节中设计了一个简单的基于多播技术的群组讨论工具,即参加讨论者可以利用MultiCastClient客户端程序加入指定的多播组,也可以随时退出该多播组。当参加者加入多播组后,便可以向该组发表自己的意见,多播组管

理机制会将任何一位参加者所发表的意见转发给该组中的各位参加者。如图6.9所示。图6.9群组讨论流程第6章TCP/UDP编程476.5多播编程6.5.3基于UdpClient的多播实例代码实例6.6MultiCastClient客户端程序using

System;usingSystem.Collections;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Collections.Generic;usingSystem.Text;namespaceMultiCastClient{/

/组播类classMultiCastClient{staticbyte[]EncodingASCII(stringbuf)//编码{byte[]data=Encoding.ASCII.GetBytes(buf+"\r\n");returndata;}staticstring

DecodingASCII(byte[]buf)//解码{stringst=Encoding.ASCII.GetString(buf);returnst;}staticvoidMain(string[]args){stringm_groupIP="234.5.6.11";int

m_port=7777;intm_ttl=2;UdpClientm_client;boolrt=false;byte[]data;stringm_SendData,m_ReturnData;IPEndPointm_EndPoint;第6章TCP/UDP编程486.5多

播编程6.5.3基于UdpClient的多播实例//从命令行参数提取组播地址和端口if(args.Length<2){Console.WriteLine("Usage:MultiCastClientGroupIPport");}else{m_groupIP=args[0].ToStrin

g();m_port=int.Parse(args[1].ToString());rt=true;}if(rt){IPAddressm_ipA=IPAddress.Parse(m_groupIP);m_EndPoint=newIPEndPoint(m_ipA,m_port);m_

client=newUdpClient();while(true){//输入命令Console.WriteLine("Input[ADD|DEL|REF|QUIT|Message]:");//加入、退出、刷新显示、退出、发送信息m_Se

ndData=Console.ReadLine();if(m_SendData.IndexOf("ADD")>-1)//加入组播{m_client.JoinMulticastGroup(m_ipA,m_ttl);}elseif(m_SendData.I

ndexOf("DEL")>-1)//退出组播{m_client.DropMulticastGroup(m_ipA);}第6章TCP/UDP编程496.5多播编程6.5.3基于UdpClient的多播实例els

eif(m_SendData.IndexOf("QUIT")>-1)//退出系统前退出组播{m_client.DropMulticastGroup(m_ipA);}if(m_SendData.IndexOf("REF")<=-1)//刷新

显示{data=EncodingASCII(m_SendData);m_client.Send(data,data.Length,m_EndPoint);}if(m_SendData.IndexOf("QUIT")>-1)//退出系统break;data=m_client.Re

ceive(refm_EndPoint);//接收并显示m_ReturnData=DecodingASCII(data);Console.WriteLine(m_ReturnData);}Console.WriteLine("Byte!");//退出m_cli

ent.Close();}}}}

小橙橙
小橙橙
文档分享,欢迎浏览!
  • 文档 25747
  • 被下载 7
  • 被收藏 0
相关资源
广告代码123
若发现您的权益受到侵害,请立即联系客服,我们会尽快为您处理。侵权客服QQ:395972555 (支持时间:9:00-21:00) 公众号
Powered by 太赞文库
×
确认删除?