VisualC#.Net网络程序开发-Socket篇
作者:宋华
作者:www.ASPCool.com
Microsoft.NetFramework为应用程序访问Internet提供了分层的、可扩展的以及受管辖的网络服务,其名字空间System.Net和System.Net.Sockets包含丰富的类可以开发多种网络应用程序。.Net类采用的分层结构允许应用程序在不同的控制级别上访问网络,开发人员可以根据需要选择针对不同的级别编制程序,这些级别几乎囊括了Internet的所有需要--从socket套接字到普通的请求/响应,更重要的是,这种分层是可以扩展的,能够适应Internet不断扩展的需要。
抛开ISO/OSI模型的7层构架,单从TCP/IP模型上的逻辑层面上看,.Net类可以视为包含3个层次:请求/响应层、应用协议层、传输层。WebReqeust和WebResponse代表了请求/响应层,支持Http、Tcp和Udp的类组成了应用协议层,而Socket类处于传输层。可以如下示意:
可见,传输层位于这个结构的最底层,当其上面的应用协议层和请求/响应层不能满足应用程序的特殊需要时,就需要使用这一层进行Socket套接字编程。
而在.Net中,System.Net.Sockets命名空间为需要严密控制网络访问的开发人员提供了WindowsSockets(Winsock)接口的托管实现。System.Net命名空间中的所有其他网络访问类都建立在该套接字Socket实现之上,如TCPClient、TCPListener和UDPClient类封装有关创建到Internet的TCP和UDP连接的详细信息;NetworkStream类则提供用于网络访问的基础数据流等,常见的许多Internet服务都可以见到Socket的踪影,如Telnet、Http、Email、Echo等,这些服务尽管通讯协议Protocol的定义不同,但是其基础的传输都是采用的Socket。
其实,Socket可以象流Stream一样被视为一个数据通道,这个通道架设在应用程序端(客户端)和远程服务器端之间,而后,数据的读取(接收)和写入(发送)均针对这个通道来进行。
可见,在应用程序端或者服务器端创建了Socket对象之后,就可以使用Send/SentTo方法将数据发送到连接的Socket,或者使用Receive/ReceiveFrom方法接收来自连接Socket的数据;
针对Socket编程,.NET框架的Socket类是Winsock32API提供的套接字服务的托管代码版本。其中为实现网络编程提供了大量的方法,大多数情况下,Socket类方法只是将数据封送到它们的本机Win32副本中并处理任何必要的安全检查。如果你熟悉WinsockAPI函数,那么用Socket类编写网络程序会非常容易,当然,如果你不曾接触过,也不会太困难,跟随下面的解说,你会发觉使用Socket类开发windows网络应用程序原来有规可寻,它们在大多数情况下遵循大致相同的步骤。
在使用之前,你需要首先创建Socket对象的实例,这可以通过Socket类的构造方法来实现:
publicSocket(AddressFamilyaddressFamily,SocketTypesocketType,ProtocolTypeprotocolType);
其中,addressFamily参数指定Socket使用的寻址方案,socketType参数指定Socket的类型,protocolType参数指定Socket使用的协议。
下面的示例语句创建一个Socket,它可用于在基于TCP/IP的网络(如Internet)上通讯。
Sockets=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
若要使用UDP而不是TCP,需要更改协议类型,如下面的示例所示:
Sockets=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
一旦创建Socket,在客户端,你将可以通过Connect方法连接到指定的服务器,并通过Send/SendTo方法向远程服务器发送数据,而后可以通过Receive/ReceiveFrom从服务端接收数据;而在服务器端,你需要使用Bind方法绑定所指定的接口使Socket与一个本地终结点相联,并通过Listen方法侦听该接口上的请求,当侦听到用户端的连接时,调用Accept完成连接的操作,创建新的Socket以处理传入的连接请求。使用完Socket后,记住使用Shutdown方法禁用Socket,并使用Close方法关闭Socket。其间用到的方法/函数有:
Socket.Connect方法:建立到远程设备的连接
publicvoidConnect(EndPointremoteEP)(有重载方法)
Socket.Send方法:从数据中的指示位置开始将数据发送到连接的Socket。
publicintSend(byte[],int,SocketFlags);(有重载方法)
Socket.SendTo方法将数据发送到特定终结点。
publicintSendTo(byte[],EndPoint);(有重载方法)
Socket.Receive方法:将数据从连接的Socket接收到接收缓冲区的特定位置。
publicintReceive(byte[],int,SocketFlags);
Socket.ReceiveFrom方法:接收数据缓冲区中特定位置的数据并存储终结点。
publicintReceiveFrom(byte[],int,SocketFlags,refEndPoint);
Socket.Bind方法:使Socket与一个本地终结点相关联:
publicvoidBind(EndPointlocalEP);
Socket.Listen方法:将Socket置于侦听状态。
publicvoidListen(intbacklog);
Socket.Accept方法:创建新的Socket以处理传入的连接请求。
publicSocketAccept();
Socket.Shutdown方法:禁用某Socket上的发送和接收
publicvoidShutdown(SocketShutdownhow);
Socket.Close方法:强制Socket连接关闭
publicvoidClose();
可以看出,以上许多方法包含EndPoint类型的参数,在Internet中,TCP/IP使用一个网络地址和一个服务端口号来唯一标识设备。网络地址标识网络上的特定设备;端口号标识要连接到的该设备上的特定服务。网络地址和服务端口的组合称为终结点,在.NET框架中正是由EndPoint类表示这个终结点,它提供表示网络资源或服务的抽象,用以标志网络地址等信息。.Net同时也为每个受支持的地址族定义了EndPoint的子代;对于IP地址族,该类为IPEndPoint。IPEndPoint类包含应用程序连接到主机上的服务所需的主机和端口信息,通过组合服务的主机IP地址和端口号,IPEndPoint类形成到服务的连接点。
用到IPEndPoint类的时候就不可避免地涉及到计算机IP地址,.Net中有两种类可以得到IP地址实例:
IPAddress类:IPAddress类包含计算机在IP网络上的地址。其Parse方法可将IP地址字符串转换为IPAddress实例。下面的语句创建一个IPAddress实例:
IPAddressmyIP=IPAddress.Parse("192.168.1.2");
Dns类:向使用TCP/IPInternet服务的应用程序提供域名服务。其Resolve方法查询DNS服务器以将用户友好的域名(如"host.contoso.com")映射到数字形式的Internet地址(如192.168.1.1)。Resolve方法返回一个IPHostEnty实例,该实例包含所请求名称的地址和别名的列表。大多数情况下,可以使用AddressList数组中返回的第一个地址。下面的代码获取一个IPAddress实例,该实例包含服务器host.contoso.com的IP地址。
IPHostEntryipHostInfo=Dns.Resolve("host.contoso.com");
IPAddressipAddress=ipHostInfo.AddressList[0];
你也可以使用GetHostName方法得到IPHostEntry实例:
IPHosntEntryhostInfo=Dns.GetHostByName("host.contoso.com")
在使用以上方法时,你将可能需要处理以下几种异常:
SocketException异常:访问Socket时操作系统发生错误引发
ArgumentNullException异常:参数为空引用引发
ObjectDisposedException异常:Socket已经关闭引发
在掌握上面得知识后,下面的代码将该服务器主机(host.contoso.com的IP地址与端口号组合,以便为连接创建远程终结点:
IPEndPointipe=newIPEndPoint(ipAddress,11000);
当前1/2页12下一页阅读全文