
Socket又称为套接字,是采用客户/服务器模型设计的网络通信接口。Socket接口最早使用在Unix系统中,Windows提供的Socket通信称为WinSock,目前存在v1.1版本(被封装在WinSock.dll动态链接库文件中)和v2.0版本(被封装在WS2_32.dll动态链接库文件中)。v1.1版本是针对Internet而设计的,在v2.0版本中已经不再局限于TCP/IP协议,而是根据Microsoft提出的Windows开放系统架构(Windows Open System Architecture,WOSA)模型,定义了一个标准服务提供接口(Standard Service Provider Interface,SPI)。通过SPI编程接口,WinSock的应用范围扩大到绝大部分的网络和协议。
.NET Framework在System.Net.Sockets名空间提供了对WinSock的托管封装,提供
在这些类中,Socket类为核心类,它提供了使用WinSock进行网络通信的基本功能。一、网络编程概念
网络中主机间的通信是通过网络协议实现的。目前,存在两种网络通信协议模型:开放系统互连(Open System Interconnection,OSI)参考模型和TCP/IP模型。
1、OSI参考模型
OSI参考模型是一个多层通信协议模型,所谓开放是指允许任意两个具有不同基本体系结构的系统进行通信的一套协议族。OSI参考模型最初是由国际化标准组织(International Standard Organization,ISO)开发,1983年成为国际标准。
OSI参考模型将网络划分成7层,从上之下分别是:应用层(Application Layer)、表示层(Presentation Layer)、会话层(Session Layer)、传输层(Transport Layer)、网络层(Network Layer)、数据链路层(Data Link Layer)和物理层(Physical Layer)。其中,每一层只与其上下两层直接通信,高层协议偏重于处理用户服务和各种应用请求,底层协议注重于处理实际的信息传输。分层的目的是在于将各种特定的功能分离,并使其实现对其他层来说是透明且相互的。
下图描述了一个包含通信子网的OSI网络通信模型。
(1)物理层
物理层定义了与物理介质的连接机制,而不是物理介质本身。按照OSI模型,物理层在物理介质之上,它提供以比特(Bit)为单位形成比特流来传送来自数据链路层的数据,而
不理会数据的格式和含义,同样,当接受数据(比特流)时也不加分析直接传送到数据链路层。即对二进制数据(比特)进行编码(发送到物理介质上)和解码(从物理介质上接受)。如:以太网的曼切斯特编码,光纤分布式接口(Fiber Distributed Data Interface,FDDI)的
4B5B编码。
物理层也负责通知数据链路层何时访问介质,如以太网的载波监听功能。此外,在某种程度上,物理层也包含连接策略,主要有:电路交换、报文交换和分组交换。
(2)数据链路层
数据链路层也称为链路控制层(Data Link Control Layer,DLC),负责管理数据格式、链路的管理、相邻网络节点的信息流动以及流量控制。
在数据链路层中,数据常以帧(Frame)为单位进行传输,帧通常是由包含起始标志的报头或报头位、寻址信息、循环冗余码(Cyclic Redundancy Check,CRC)组成。循环冗余码用来保证帧在传输过程中的完整性,将无错的帧发送到网络层。
OSI模型中的数据链路层与电气与电子工程师协会(Institute of Electrical and ElectronicEngineers,IEEE)定义的有所不同。IEEE定义的数据链路层包含逻辑链路控制(Logical Link Control Layer,LLC)和介质访问控制(Media Access Control Layer,MAC)。MAC层基本对应OSI模型中的数据链路层,LLC层主要提供可靠的面向连接服务与无连接的数据报服务,ISO在这之上提供了两种网络层服务,即面向连接的网络服务和无连接的网络服务。
(3)网络层
网络层提供跨越多个网络的路由和寻址功能,使两个终端系统能够以最佳路径进行互连,并具有一定的堵塞控制和流量控制能力。
在网络层中,通常以数据包(Packet)为单位传输数据。在数据包中可以包含一个16位的校验和,但这个校验和可能只能保证网络层包头的信息,而不能保证数据包信息。如:IP 协议(Internet Protocol)。
网络层的端到端寻址于数据链路层,网络层的寻址由网络标识附加主机标识组成。主机标识指明网络或子网中的一个节点;网络标识可能是子网化的IP,单调的IPX(Internet Packet Exchange),也可能是层次化的DECnet(Digital Equipment Corporation's net)。路由信息协议(Routing Information Protocol,RIP),或开放式最短路径优先(Open Shortest Path First,OSPF)这些协议将有关网络标识的信息广播到其他路由器,以便可以转发相应
的数据包。
在网络维护中,所使用的Ping指令是在应用层直接使用网络层的ICMP协议(Internet Control Message Protocol)的服务指令。
(4)传输层
传输层是一个过渡性层次,在其下3层主要处理网络通信,发送方和接收方之间的每个节点都必须执行下3层的协议,确保数据被准确有效地传输;在传输层及其上3层主要为用户提供服务,工作于发送节点和接受节点之上,确保数据被正确接受,并答复发送节点。
传输层在两个通信系统之间建立一条通信链路,允许其上3层不受实际网络结构的约束执行各自的任务,同时依靠其下3层控制实际的网络操作,监督数据从源节点出发,最终到达目标节点。
传输层还处理一些由网络层引起的错误,如包丢失、重复包等等,同时还可以对包进行重新排序、分段(用于传输大的报文)和重装,这有助于在网络发生拥塞时降低发送数据的速率。此外,传输层还包括多路复用、连接管理等。
(5)会话层
会话层提供命名服务,实现逻辑名到网络地址的映射;允许不同主机上的应用程序进行会话或建立虚连接;为丢失的连接事件提供检查。
会话层使用逻辑名或别名建立会话,通常在会话建立之后在数据报中嵌入会话标志。不同系列的协议都提供查找与地址相关逻辑名的方法,如:TCP/IP协议族使用域名服务系统(Domain Name System,DNS),IPX/SPX采用NetWare服务广播协议(Service Advertising Protocol,SAP)。
会话层协议还包括NetBIOS(Network Basic Input and Output Service)、远程过程调用(Remote Procedure Call,RPC)等。
(6)表示层
表示层用于解决信息与数据的区别。数据是信息的载体,信息是人为赋予的含义,在计算机中表示的比特位不能表达其内容,并且不同计算机表示相同信息的方式各不相同。
表示层管理抽象的数据结构,定义数据的语法和语义,提供数据压缩、解压、加密、解密等服务,在必要时可以对应用层的数据进行转换。
(7)应用层
应用层直接与用户或应用程序通信,它通过Shell或转向器(Redirector)机制来支持本地操作系统。它将文件、打印和消息服务的API(Application Programming Interface,应用程序接口)转换成通用语言,如:Windows系统中的服务器消息块(Server Message Block,SMB),实现对不同操作系统的支持。
典型的网络应用有WWW服务、电子邮件、文件传输、虚拟终端、分布式系统等。
在使用OSI的7层模型进行数据传递过程中,每一层都对网络数据流都加上报头进行重新封装或重组,其传递过程可用下图描述:
2、TCP/IP模型
OSI参考模型常作为理论模型,实际应用中使用的是TCP/IP模型。TCP/IP模型是事实上的工业标准模型。TCP/IP代表一套工业标准协议套件,TCP协议和IP协议是其中最著名的协议,1969年由美国国防部高级研究计划局(Department of Defense Advanced Research Project Agency,DARPA)开发,最早应用在ARPNET上,现已形成广为人知的Internet。
TCP/IP模型将网络划分成4个层次,与OSI参考模型之间的关系可用下图说明:
(1)网络接口层
网络接口层相当于OSI模型中的数据链路层和物理层。通常包含在操作系统的设备驱动程序和网络接口设备中,它们一起处理与物理介质的物理接口细节。
(2)网际层(IP层)
网际层相当于OSI模型中的网络层,负责寻址、打包以及包转发机制。网络层协议主要包含互联网协议(Internet Protocol,IP)、互联网控制报文协议(Internet Control Message Protocol,ICMP)和互联网组管理协议(Internet Group Management Protocol,IGMP)。
IP协议是TCP/IP协议族中核心协议,所有的TCP、UDP、ICMP以及IGMP数据都是以IP数据包格式传输,它提供不可靠、无连接的数据包传送服务。这里的“不可靠”是指IP协议不能保证IP数据包能成功地传送到目标主机,IP仅提供最好的传输服务,当发生传输错误时,IP丢弃该数据包,发送ICMP消息报给发送数据的信源端;“无连接”是指IP并不维护任何有关后续数据包的状态信息,每个数据包的处理是相对的,这也说明,IP数据包可以不按发送顺序接受。
ICMP协议是面向连接的协议,用于在IP主机、路由器间传送出错报告控制消息。提供诊断功能,报告由于IP数据包投递失败而导致的错误。IGMP协议是用于组播的协议,负责管理IP组播,将UDP数据报发送给同组主机。这两个协议实际上应用到TCP层协议的内容。
在有些情况下,将地址解析协议(Address Resolution Protocol,ARP)和反向地址解析
协议(Reverse Address Resolution Protocol,RARP)也认为是网际层的一部分。这是因为这两个协议使用到网际层的功能。ARP协议通过广播方式将IP地址翻译成对应的MAC地址,与之对应的是RARP协议,它实现将MAC地址翻译成对应的IP地址。
(3)主机到主机的传输层(TCP层)
主机到主机的传输层相当于OSI模型中的传输层和部分会话层功能,它提供给应用层会话和数据报通信服务,其核心协议为传输控制协议(Transmission Control Protocol,TCP)
和用户数据报协议(User Datagram Protocol,UPD)。
TCP协议提供点到点的、面向连接的可靠通信服务,负责建立TCP连接,对发送包进
行编号和应答,并恢复在传输过程间丢失的包。
UPD协议提供点到点或点到对点、无连接的不可靠通信服务,通常用于传输少量数据。
(4)应用层
应用层负责处理特定的应用程序细节,为应用程序提供访问其他层的能力,定义应用程序用于交换数据的协议。常用的协议有:
a)域名系统(Domain Name System,DNS),用于将主机名解析成IP地址。
b)路由选择信息协议(Routing Information Protocol,RIP),用于路由器在IP网络上交换路由选择信息。
c)简单网络管理协议(Simple Network Management Protocol,SNMP),用于在网络管理控制台和网络设备(路由器、网桥、智能集线器)之间选择和交换网络管理信息。
d)网络文件系统(Network File System,NFS),用于保证网络中的主机可共享文件。
e)超文本传输协议(Hypertext Transfer Protocol,HTTP),用于传输组成Web网页的文件。
f)文件传输协议(File Transfer Protocol,FTP),用于交互式文件传输。
g)简单邮件传输协议(Simple Mail Transfer Protocol,SMTP),用于传输邮件消息。
h)终端仿真协议(Telnet),用于远程登录到网络主机。
在Windows系统中,TCP/IP应用程序使用的编程接口有Windows套接字(WinSock)和NetBIOS。WinSock是Windows系统提供的标准Socket编程接口;NetBIOS是工业标准接口,用于访问协议服务,如:会话、数据报和名字解析等。
3、端口号
在TCP协议和UDP协议中采用16位的端口号标识服务器上可应用的服务,端口号的范围是从1~65535。其中1~1024是被RFC3232规定,称作为“知名端口”(Well Known Ports );从1025~65535的端口被称为动态端口(Dynamic Ports),可用来建立与其它主机的会话,也可由用户自定义用途。
端口号主要用于服务器来区分服务类别和在同一时间进行多个会话。客户端通常并不关心它使用的端口号,只要保证在本机系统中是唯一的。
一些常见的服务器知名端口号见下表。
4、Socket编程模型
使用Socket实现网络通信时,根据使用的通信协议包含面向连接的网路通信和无连接的网络通信两种形式。
使用面向连接的网络通信时,其通信形式可用下图描述:
无连接的网络通信形式见下图:
5、客户/服务器模型
在使用客户/服务器模型使用网络服务时,服务器有两种服务类型:重复型和并发型。
重复型服务器使用如下步骤进行交互:
(1)等待一个客户的请求到来;
(2)处理客户请求;
(3)发送响应信息给请求的客户;
(4)返回第(1)步继续等待客户请求。
在该服务模式中,服务器在处理一个客户请求时,不能处理其他客户的请求。在使用Socket编程时可以使用堵塞(同步)通信方式实现。
并发型服务器使用以下步骤进行交互:
(1)等待一个客户的请求到来;
(2)启动一个新的服务器处理客户的请求,在这期间可能创建一个新的进程、任务或线程,并依赖操作系统的支持。该步骤如何进行取决于操作系统。新服务器处理完客户请求后,结束这个新的服务器。
(3)返回第(1)步等待客户请求。
并发型模型的优点是允许每个客户拥有自己的服务器,在多任务的操作系统中,可以同时为多个客户服务。在使用Socket编程时可以使用非堵塞(异步)通信方式实现。
二、创建Socket
Socket代表网络通信中的一个端点,要创建一个Socket实例,必须提供网络通信过程中的寻址方式、通信协议以及数据流类型。在Socket类中提供的构造方法签名为:Socket(AddressFamily family, SocketType streamType, ProtocolType protocol);
1、寻址方式
在.NET Framework中,使用地址族表示不同网络协议在解析地址时的寻址方式,并将
2、协议
Socket支持的协议被封装在System.Net.Sockets.ProtocolType枚举类型中。
枚举ProtocolType名空间System.Net.Sockets 说明列举Socket支持的协议
枚举名说明
Ggp网关到网关的协议
Icmp Internet控制报文协议
Idp Internet数据报协议
Igmp Internet组管理协议
IP Internet协议
IPv4IPv4的Internet协议
Ipx Internet数据包交换协议
ND网络磁盘协议(非正式)
Pup PRAC通用数据包协议
Spx顺序包交换协议
SpxII顺序包交换协议第2版
Tcp TCP协议
Udp UDP协议
Raw原始IP数据包协议
IPv6IPv6的Internet协议
IPv6DestinationOptions IPv6目标选项头
IPv6FragmentHeader IPv6片段头
IPv6HopByHopOptions IPv6逐跳选项头
IPv6NoNextHeader IPv6 No Next头
IPv6RoutingHeader IPv6路由头IPSecAuthenticationHeader IPv6身份验证头IPSecEncapsulatingSecurityPayload IPv6 封装式安全措施负载头
IcmpV6用于IPv6的互联网控制报文协议
Unknown未知协议
Unspecified未指定的协议
在使用上述类型协议时,要求操作系统上必须安装支持该协议的驱动程序,才能成功创建Socket实例。
3、数据流类型
使用Socket进行网络通信的数据流类型被封装在System.Net.Sockets.ScoketType枚举类
在.NET Framework 2.0中,还新增了重复使用某一进程的Socket实例的构造方法,其方法签名为:
Socket(SocketInformation socketInfo);
SocketInformation是使用Socket类提供的DuplicateAndClose方法获取的返回值类型,它是定义在System.Net.Sockets名空间下的结构。
结构SocketInformation名空间System.Net.Sockets 说明封装复制Socket实例信息
属性名属性类型说明
读写属性Options SocketInformationOptions Socket选项ProtocolInformation byte[ ]Socket协议信息
SocketInformationOptions是用来描述Socket实例状态的枚举类型,定义在System.Net.-
DuplicateAndClose方法用来复制目标进程的Socket实例,并关闭此进程的Socket,其签名为:
SocketInformation DuplicateAndClose(int tagetProcessId);
三、绑定或连接网络资源(服务)
当创建了Socket实例后,需要将其绑定或连接到网络资源或网络服务上。要绑定到本地资源或服务可使用Bind方法,Bind方法签名为:
void Bind(EndPoint localPoint);
要连接到网络资源或服务可使用Connect方法,Connect方法是同步连接网络资源或服务的方法,具有以下重载形式:
void Connect(EndPoint remotedPoint);
void Connect(IPAddress address, int port);
void Connect(IPAddress[ ] addresses, int port);
void Connect(string hostName, int port);
若希望使用异步方式连接网络资源或服务可以使用BeginConnect方法开始尝试连接,它具有以下重载形式:
IAsyncResult BeginConnect(EndPoint remotedPoint, AsyncCallback callback, object state);
IAsyncResult BeginConnect(IPAddress address, int port, AsyncCallback callback
, object state);
IAsyncResult BeginConnect(IPAddress[ ] addresses, int port, AsyncCallback callback
, object state);
IAsyncResult BeginConnect(string hostName, int port, AsyncCallback callback
, object state);
要结束异步连接使用EndConnect方法,它的方法签名为:
void EndConnect(IAsyncResult result);
在上述方法中,EndPoint类表示一个网络资源或服务的连接点,它实际上用来表示访问一个网络资源时的主机地址和服务端口号。EndPoint是抽象类,定义在System.Net名空间,其类的静态结构如下图所示:
在上图中,DnsEndPoint类是在.NET Framework 4.0中新增的连接点类型类,它使用域名和端口号来描述一个网络资源的连接位置。SocketAddress是用来存储EndPoint实例序列化信息的类。
1、主机IP地址
System.Net.IPAddress类封装了在描述主机IP地址时使用点分十进制表示的IPv4地址和
2、域名解析
由于在网络中一台主机可能拥有不只一个的名称或IP地址,因此.NET Framework在
3、面向连接的处理
在使用面向连接的通信方式时,当将Socket实例绑定到特定的主机地址和端口后可调用Listen方法侦听客户的连接。Listen方法的签名为:
void Listen(int blocklog);
在调用该方法时需提供允许挂起等待队列的最大长度参数。
四、面向连接的通信处理1、发送数据
Send方法用来同步发送数据,具有以下重载形式:
int Send(byte[ ] buffer);
int Send(byte[ ] buffer, SocketFlags flags);
int Send(byte[ ] buffer, int size, SocketFlags flags);
int Send(byte[ ] buffer, int offset, int size, SocketFlags flags);
int Send(byte[ ] buffer, int offset, int size, SocketFlags flags, out SocketError errorCode); int Send(IList int Send(IList int Send(IList , out SocketError errorCode); SocketError是用来描述发送或接受过程中产生错误的错误码枚举类型。 要异步发送数据,可使用BeginSend和EndSend方法实现。 BeginSend方法具有以下重载形式: IAsyncResult BeginSend(byte[ ] buffer, int offset, int size, SocketFlags flags , AsyncCallback callback, object state); IAsyncResult BeginSend(byte[ ] buffer, int offset, int size, SocketFlags flags , out SocketError errorCode, AsyncCallback callback, object state); IAsyncResult BeginSend(IList , AsyncCallback callback, object state); IAsyncResult BeginSend(IList , out SocketError errorCode, AsyncCallback callback, object state); EndSend方法具有以下重载形式: int EndSend(IAsyncResult result);int EndSend(IAsyncResult result, out SocketError errorCode); 若发送的为文件数据时,可使用SendFile方法,该方法具有以下重载形式: void SendFile(string fileName); void SendFile(string fileName, byte[ ] preBuffer, byte[ ] posBuffer , TransmitFileOptions flags); 同样发送文件数据也可以使用BeginSendFile和EndSendFile来实现异步发送处理。 BeginSendFile方法具有以下重载形式: IAsyncResult BeginendSendFile(string fileName, AsyncCallback callback, object state); IAsyncResult BeginSendFile(string fileName, byte[ ] preBuffer, byte[ ] posBuffer , TransmitFileOptions flags, AsyncCallback callback, object state); 结束异步发送处理使用EndSendFile方法,其方法签名为: void EndSendFile(IAsyncResult result); 2、接受方法 Receive方法用来同步接受数据,具有以下重载形式: 要异步接受数据,可使用BeginReceive和EndReceive方法实现。 BeginRecive方法具有以下重载形式: EndReceive方法的签名为: 五、无连接的通信处理 六、TCP协议的封装 为了简化TCP协议的Socket编程,.NET Framework提供了TcpListener和TcpClient两个使用TCP协议的Socket封装类,它们都定义在System.Net.Sockets名空间。 1、TcpListener类 TcpListener类提供使用同步堵塞方式侦听TCP客户连接的Socket封装类,具有以下属 2、TcpClient类 七、UDP协议的封装 System.Net.Sockets.UdpClient类封装了UDP协议,它提供了以下属性和方法来使用
