Socket类:这个低层的类用于管理连接,实现Berkeley通信端接口,定义绑定、连接网络端点以及传输数据所需的方法,提供处理端点连接传输等细节所需要的功能。WebRequest、TcpClient和UdpClinet等类在内部使用这个类。
TcpClient类:允许创建和使用TCP连接,其创建于Socket类的基础上,并且封装了许多更高级的功能,避免开发人员处理连接操作的相关细节。
TcpListener类:允许监听传入的TCP连接请求,倾听来自TCP客户端应用程序的连接要求,封装更高级的功能,使用这个类同样也可以让你避免处理一些连接服务的细节,以一种比较有效它率的方式,接受倾听的连接需求。
UdpClinet类:用于为UDP客户创建连接(UDP是另一种TCP协议,但没有得到广泛的使用,主要用于本地网络)。
NetWorkStream类:这个类是从Stream派生出来的,专门用以处理网络形式的数据流,与其他文件数据流最大不同的地方在于,这个类接受Socket类对象参数,对网络数据进行存取操作。
1 套接字
.NET Framework Socket类是Winsock32 API提供的套接字服务的托管代码版本。在大多数情况下,Socket类方法只是将数据封送到它们的本机Win32副本中,并处理任何必要的安全检查。
Socket类支持两种基本模式:同步和异步。在同步模式中,对执行网络操作的函数(如Send和Receive)的调用一直等到操作完成后才将控制返回给调用程序,而在异步模式中,这些调用立即返回。
在可以使用套接字与远程设备通信之前,必须使用协议和网络地址信息初始化套接字。Socket类的构造函数具有指定套接字用来建立连接的地址族、套接字类型和协议类型的参数等功能。
在基于TCP/IP的网络(如Internet)上通信的关键代码如下:
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
要使用UDP而不是TCP进行通信的关键代码如下:
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
参数:
AddressFamily :AddressFamily枚举,用来指定Socket类用来解析网络地址的标准地址族。
SocketType: SocketType枚举,用来指定套接字的类型。
ProtocolType: ProtocolType枚举,用来指定在Socket上通信时使用的网络协议。
创建Socket后,它既可以开始与远程终结点的连接,也可以接收来自远程设备的连接。
2 Socket类的属性、方法
本节将主要介绍Socket类的属性和方法,以便为读者使用Socket类进行网络编程提供方便。
Socket类的属性
Socket类常用属性及说明如表所示。
表
名称 | 说明 |
AddressFamily | 获取Socket的地址族 |
Available | 获取已经从网络接收且可供读取的数据量 |
Blocking | 获取或设置一个值,该值指示Socket是否处于阻止模式 |
Connected | 获取一个值,该值指示Socket是在上次Send还是Receive操作时连接到远程主机 |
DontFragment | 获取或设置Boolean值,该值指定Socket是否允许将Internet协议(IP)数据报分段 |
EnableBroadcast | 获取或设置一个Boolean值,该值指定Socket是否可以发送或接收广播数据包 |
ExclusiveAddressUse | 获取或设置Boolean值,该值指定Socket是否仅允许一个进程绑定到端口 |
Handle | 获取Socket的操作系统句柄 |
I sBound | 获取一个值,该值指示Socket是否绑定到特定本地端口 |
LingerState | 获取或设置一个值,该值指定Socket在尝试发送所有挂起数据时是否延迟关闭套接字 |
LocalEndPoint | 获取本地终结点 |
MulticastLoopback | 获取或设置一个值,该值指定传出的多路广播数据包是否传递到发送应用程序 |
NoDelay | 获取或设置Boolean值,该值指定流Socket是否正在使用Nagle算法 |
OSSupportsIPv6 | 指示基础操作系统和网络适配器是否支持Internet协议第6版 |
ProtocolType | 获取Socket的协议类型 |
ReceiveBufferSize | 获取或设置一个值,它指定Socket接收缓冲区的大小 |
ReceiveTimeout | 获取或设置一个值,该值指定之后同步Receive调用将超时的时间长度 |
RemoteEndPoint | 获取远程终结点 |
SendBufferSize | 获取或设置一个值,该值指定Socket发送缓冲区的大小 |
SendTimeout | 获取或设置一个值,该值指定之后同步Send调用将超时的时间长度 |
SocketType | 获取Socket的类型 |
UseOnlyOverlappedIO | 指定套接字是否应仅使用重叠I/O模式 |
下面对比较重要的属性进行详细介绍。
(1)AddressFamily属性
获取Socket的地址族。
语法:
public AddressFamily AddressFamily { get; }
本示例实现的是当程序运行时,单击窗体中的【获取地址族】按钮,在窗体的文本框中显示出当前Socket对应的地址族,本示例在实现时,首先引入System.Net.Sockets命名空间,然后在窗体中添加一个Lable控件(用于显示信息)、一个TextBox控件(用于显示结果)和一个Button控件(用于触发事件)。
程序主要代码如下。
在窗体加载时,实例化Socket对象(sk)、将Socket的地址族设为InterNetwork、将Socket的类型设为Stream类型、将Socket的协议类型设为Tcp类型。FrmSockect窗体的Load事件代码如下:
(2)DontFragment属性:
获取或设置Boolean值,该值指定Socket是否允许将Internet协议(IP)数据报分段。
语法:
public bool DontFragment { get; set; }
(3)EnableBroadcast属性:
获取或设置一个Boolean值,该值指定Socket是否可以发送或接收广播数据包。
语法:
public bool EnableBroadcast { get; set; }
(4)MulticastLoopback属性:
获取或设置一个值,该值指定传出的多路广播数据包是否传递到发送应用程序。
语法:
public bool MulticastLoopback { get; set; }
本示例实现的是当程序运行时,在窗体的3组单选框中显示出当前Socket对应的属性信息.本示例在实现时,需在引入System.Net.Sockets命名空间,然后在窗体中添加3个Lable控件(用户显示提示信息)、6个RadioButton控件(用于显示结果信息)和3个groupBox(用于分组显示控件)。
程序主要代码如下:
private void FrmDont_Load(object sender, EventArgs e)
在窗体的Load事件中调用了ConfigureUdpSocket方法,该方法主要用来为Socket设置相应的属性,其关键代码如下:
void ConfigureUdpSocket(Socket udpSocket)
Socket类的方法
Socket类的常用方法及说明如表所示。
表
名称 | 说明 |
BeginConnect | 已重载。 开始一个对远程主机连接的异步请求 |
BeginSend | 已重载。 将数据异步发送到连接的Socket |
BeginSendTo | 向特定远程主机异步发送数据 |
BeginSendFile | 已重载。 将文件异步发送到连接的Socket对象 |
Listen | 将Socket置于侦听状态 |
SendTo | 已重载。 将数据发送到特定终结点 |
Shutdown | 禁用某Socket上的发送和接收 |
EndSend | 已重载。 结束挂起的异步发送 |
EndSendFile | 结束文件的挂起异步发送 |
EndSendTo | 结束挂起的、向指定位置进行的异步发送 |
下面对比较重要的方法进行详细介绍。
(1)BeginConnect 方法:
开始一个对远程主机连接的异步请求,主机由 IPAddress 和端口号指定。
语法:
public IAsyncResult BeginConnect
(
)
参数:
address:远程主机的IPAddress。
Port:远程主机的端口号。
RequestCallback:一个AsyncCallback委托,它引用连接操作完成时要调用的方法。
State:一个用户定义对象,其中包含连接操作的相关信息。当操作完成时,此对象会被传递给requestCallback委托。
返回值:IAsyncResult,它引用异步连接。
本示例中通过Socket类的BeginConnect方法发起一次异步连接尝试。实现的相关程序代码如下:
(2)Bind 方法:
使Socket与一个本地终结点相关联。
语法:
public void Bind
(
)
参数
localEP:要与Socket关联的本地EndPoint。
(3)Listen方法:
将 Socket 置于侦听状态。
语法:
public void Listen
(
)
参数:
backlog:挂起连接队列的最大长度。
本示例中通过Socket类的Listen方法来侦听传入的连接。程序主要代码如下。
private void FrmListinMothed_Load(object sender, EventArgs e)
(4)SendTo方法:
将数据发送到指定的终结点。
语法:
public int SendTo
(
)
参数:
buffer:Byte类型的数组,它包含要发送的数据。
RemoteEP:EndPoint(标识网络地址,是一个abstract类),它表示数据的目标位置。
返回值:已发送的字节数。
本示例中通过Socket类的SendTo方法来将数据发送到指定的终结点。程序主要代码如下。
public