1【转】C#Socket网络编程入门第一章C#Socket编程(1)基本的术语和概念计算机程序能够相互联网,相互通讯,这使一切都成为可能,这也是当今互联网存在的基础。那么程序是如何通过网络相互通信的呢?这就是我记录这系列的笔记的原因。C#语言从一开始就是为了互联网而设计的,它为实现程序的相互通信提供了许多有用API,这类应用编程接口被称为套接字(Socket)。在开始学习C#Socket之前我们需要先来了解一下基本的术语和概念。1.1计算机网络计算机网络由一组通过通信信道(Communicationchannel)相互连接的机器组成。这些机器被称为:主机(hosts)和路由器(routers)。*通信信道——是将字节序列从一个主机传输到另一个主机的一种手段(有线、无线(WiFi)等方式)。*主机——是运行程序的计算机。*路由器——是将信息从一个通信信道传递或转发到另一个通信信道。TCP/IP网络通信流程图:21.2分组报文*分组报文——在网络环境中由程序创建和解释的字节序列。1.3协议协议相当于相互通信的一种约定,协议规定了分组报文的交换方式和它们包含意义。互联网所使用的协议是TCP/IP协议,TCP/IP协议族主要包括:*IP协议(InternetProtocol,互联网协议)*TCP协议(TransmissionControlProtocol,传输控制协议)*UDP协议(UserDatagramProtocol,用户数据报协议)1.3.1IP协议*IP协议——是TCP/IP协议中唯一属于网络层的协议。将数据从一台主机传输到另一台主机。*IP协议——提供了一种数据服务:每组分组报文都有网络独立处理和分发,类似于信件或包裹通过邮政系统发送一样。*IP协议——是一个尽力而为(best-effort)的协议:它试图分发每一个分组报文,在网络传输过程中,偶尔也会发生丢失报文或报文顺序打乱,或者重复发送报文的情况。在IP协议层之上是传输层(transportlayer),它提供了两种可选的协议:TCP协议和UDP协议,两种协议都建立在IP层所提供的服务基础上,二者也被称为端到端传输协议(end-to-endtransportprotocol)。根据应用程序协议3(Applicationprotocol)的不同需求,使用了不同的方式传输数据。二者都有一个共同的功能:寻址。TCP协议和UDP协议使用的地址叫做端口号(portnumber),是用来区分同一主机不同应用程序的。1.3.2TCP协议TCP协议能够检测和恢复IP层提供的主机到主机的信道中可能发生的报文丢失、重复以及其他错误。TCP协议是一种面向连接(connectionoriented)协议:在使用它进行通信之前,两个应用程序之间首先要建立一个TCP连接,这涉及两台相互通信的主机的TCP部件间完成的握手消息(handshakemessage)的交换。1.3.3UDP协议UDP协议并不尝试对IP层产生的错误进行修复,它仅仅简单拓展了IP协议,尽力而为的数据服务,使它能够在应用程序之间工作,而不是在主机之间工作。使用UDP协议的应用程序需要对处理报文丢失、顺序混乱等问题做好准备。1.4网络地址1.4.1IP地址在TCP/IP协议中,有两部分信息用来定位一个指定的程序:互联网地址(Internetaddress)和端口号(portnumber,范围1-65535)。前者由IP协议使用,后者由传输协议(TCP/UDP)对其进行解析。互联网地址由二进制数字组成,有两种形式:IPv4(32位)和IPv6(1284位)。为了方便使用,两个版本的IP协议有不同的表示方法:IPv4地址被表示为一组为4个十进制数,每两个数之间用圆点隔开,这种表示方法叫做:点分形式(dotted-quad)。IPv6地址的16个字节由几组16进制的数字表示,这些十六进制数之间有分号隔开,每组数字分别代表了地址中的两个字节。1.4.2回环地址回环地址(loopbackaddress)是被分配的一个特殊的回环接口(loopbackinterface),回环接口是一种虚拟设备,它的功能只是简单的把发送给它的报文立即返回给发送者。如IPv4中的127.0.0.11.5域名系统(DomainNameSystem,DNS)和本地配置数据库DNS是一种分布式数据库,它将像这样的域名映射到真实的互联网地址和其他信息上。DNS协议允许连接到互联网的主机通过TCP或者UDP协议从DNS数据库获取信息。本地配置数据库通常是一种与具体操作系统相关的机制,用来实现本地与互联网地址的映射。1.6客户端和服务器客户端(client)和服务器(server)这两个术语分别代表了两种角色:*客户端是通信的发起者,而服务器程序则被动等待客户端发起通信,并5对其作出响应。*客户端和服务器组成了应用程序。1.7什么是Socket(套接字)Socket(套接字)是一种抽象层,应用程序通过它来发送和接受数据,就像应用程序打开一个文件句柄,将数据读写到稳定的存储器上一样。在TCP/IP协议族中的主要Socket类型为:*流套接字(streamsocket):传输层使用TCP协议,提供了一个可信赖的字节流服务*数据报套接字(datagramsocket):传输层使用UDP协议,提供了一个尽力而为的数据报服务,最长一次可以发送65500个字节的数据。第二章C#Socket编程(2)识别网络主机通过前面的笔记我们可以知道:一个客户端想要发起一次通信,先决条件就是需要知道运行着服务器端程序的主机的IP地址是多少,端口号是多少。然后我们才能够通过这个地址向服务器特定的应用程序发送信息。对于网络上的两台计算机来说,用户操作的计算机称为本地主机,与该计算机通信的另一台计算机称为远程主机。识别远程主机依靠两部分组成:一是主机标识,用于识别与本地主机通信的远程主机;二是端口号,用于识别是在和远程主机中的哪个进程通信。62.1获取主机地址信息在C#开发中System.Net命名空间为网络上使用的多种协议提供了简单的编程接口。我们可以利用这个命名空间下的类,编写基于网络标准协议的应用程序时,不必去考虑各种不同协议的具体细节。在获取主机(local和remote)地址信息时,我们需要使用和学习这几个最基本的类(更加详细API可以参考MSDN,下面会给出对应链接),用它们来实现相关的功能。*提供网际协议的IP地址的IPAddress类*包含IP地址和端口号的IPEndPoint类*为Internet主机提供信息容器的IPHostEntry类*提供简单的域名解析功能的Dns类说千遍不如做一遍,学习编程的最好方式就是自己动手实践,下面我们通过创建一个简单的WindowsForms示例程序(下载地址在本章末尾)来学习如何获取网络主机的地址信息,下面是示例的示例代码主要代码:1//获取本地主机名2stringlocalHostName=Dns.GetHostName();34//通过主机名获取该主机下存储所有IP地址信息的容器5IPHostEntrylocal=Dns.GetHostEntry(HostName);67//通过IPHostEntry对象的AddressList属性获取相关联主机的所有IP地址8IPAddress[]ipList=local.AddressList;7910//获取本机回环地址11IPAddressloopbackIP=IPAddress.Loopback;1213//通过它Parse函数构造IPAddress对象14IPAddresslocalIp=IPAddress.Parse(192.168.1.101);1516//通过IPAddress对象和端口号构造IPEndPoint对象17IPEndPointiep=newIPEndPoint(localIp,80);查看运行示例程序效果:82.2获取网卡信息和网络检测网络适配器又被称为网卡或者网络接口卡(NIC),是连接计算机和网络的硬件设备。网卡主要的工作原理是:整理计算机发往信道上的数据,并将数据分解为适当大小的数据包之后向网络上发送。在.NET开发中我们使用System.Net.NetworkInformation命名空间获取:网络流量数据、网络地址信息和本地计算机的地址更改通知等信息。该命名空间还包含实现Ping实用工具的类。可以使用Ping和相关的类检查是否可通过网络连接到计算机。2.2.1获取网卡信息获取网卡信息、网络连接和网络速度以及网络协议版本(包括:IPv4和IPv6)的网络接口信息,我们使用下面的两个类:1.NetworkInterface类:提供了访问主机所有接口的信息的功能。利用该类我们可以方便的检测本机有多少个网卡、哪些网络连接可用、并获取某个网卡的型号、Mac地址和速度等信息。2.IPInterfaceProperties类:可用于访问支持IPv4或IPv6的网络接口的配置和地址信息。该类是一个抽象类,不能直接创建,使用NetworkInterface.GetIPProperties()返回实例。下面我们通过一个简单的WindowsForms示例程序来学习如何获取网络接口的配置和统计信息,主要代码如下:1//获取主机上所有的网络适配器对象数组2NetworkInterface[]adapters=NetworkInterface.GetAllNetworkInterfaces();934//获取该网络适配器的配置对象5IPInterfacePropertiesadapterProperties=adapters[i].GetIPProperties();67//获取该网络适配器DNS服务器地址信息8IPAddressCollectiondnsServers=adapterProperties.DnsAddresses;运行实例程序效果:2.2.2网络流量检测我们可以使用System.Net.NetworkInformation命名空间的IPGlobalProperties类获取网络适配器接收、转发、丢弃、发送的数据包数目,该类提供有关本地计算机的网络连接的信息。检测网络流量是我们通过使用IPGlobalProperties类10的GetIPGlobalProperties()方法获取记录本地计算机的网络连接和通信统计数据的信息的对象实例,通过实例的属性来获取相关信息,达到检测网络流量的目的:1//获取包含本机的网络连接和通信统计数据的信息的对象2IPGlobalPropertiesproperties=IPGlobalProperties.GetIPGlobalProperties();34//获取本机IPv4统计数据5IPGlobalStatisticsipstate=properties.GetIPv4GlobalStatistics();下面我们还是通过上面的代码来创建一个小例子来学习如何检测网络流量,程序运行效果如下:2.2.3网络连接检测我们知道可以利用CMD命令行中输入的ping命令,通过调用ping.exe命令行程序来检测网络连接,能够快速判断出网络故障。在.NET开发环境中我们可以通过使用System.Net.NetworkInformation命名空间下的Ping类、PingOptions11类和PingReply类来实现类似于ping.exe命令行的功能。*Ping类可以帮助应用程序确定是否可通过网络访问远程计算机*PingOptions类用于控制如何传输Ping数据包*PingReply类提供有关Send或SendAsync操作的状态及产生的数据的信息。示例程序主要代码如下:1//获取主机地址2stringhostAddress=this.txt_HostAddress.Text.Trim();3//构造Ping实例4PingpingSender=newPing();5//Ping选项设置6PingOptionsoptio