【C#学习笔记07】网络编程技术
#本篇仅时C#网络编程技术基础,对于网络技术浅尝辄止,并未深度剖析网络技术细节#

1. 计算机网络基础
1.1 局域网与广义网
LAN:Local Area Network,局域网,在某一区域内堕胎计算机通过一定形式连接起来的计算机组;
WAN:Wide Area Network,广域网,由LAN延申到更大的范围,称为广域网,比如我们所熟悉的因特网(Internet);
1.2 网络协议
网络协议固定了计算机之间连接的物理、机械(网线与网卡的连接规定)、电器(有效的电平范围)等特性,以及计算机之间的相互寻址规划、数据发送冲突解决、长数据如何分段传送与接受等。目前常用的网络协议存在多种,常见网络协议如下:
1.2.1 IP协议
IP的全程是Internet(互联网) Protocol(协议)。Internet采用的协议是TCP/IP协议,全称是Transmission(传输) Control(控制) Protocol(协议)/Internet(互联网) Protocol(协议),依靠TCP/IP协议,Internet在全球范围内实现不同硬件结构、不同操作系统、不同网络系统的互联。由于Internet中存非常多的主机,每台主机在网络上通过为其分配Internet地址标识自己,这个地址就是IP地址。
1.2.2 TCP协议
TCP协议是一种以固定连线为基础的协议,可提供两台计算机见可靠的数据传输,也就是需要两台计算机先连线再互通;
1.2.3 UDP协议
UPD协议是无连接通信协议,可向多个目标发送数据,接收多个源的数据,不保证可靠的数据传输,相当于广播。
1.3 端口与套接字
端口(Port)并非真实的物理端口,而是一个假定的连接装置。端口被规定为一个再0-65536间的整数,相当于在物理网络的基础上增加一个拓展插排;
套接字(Socket)用于将程序与网络连接起来,也是个非物理的连接装置,相当于程序连接到插排的连接方式;
C#将套接字抽象化为类,我们只需要创建Socket类对象,就可以使用套接字。
2. IP地址封装
IP地址是么格局计算机在网络中的唯一标识,它是32位或128位的无符号数字,使用四组数字表示的一个固定编号,比如:192.168.0.1就是局域网络中的编号
IP地址是一种低级协议,TCP协议和UDP协议都是在它的基础上构建的。
C#提供了IP地址相关的类,包括Dns类,APAddress类、IPHostEntry类等,他们都维护System.NET命名空间中。
2.1 Dns类
Dns类是一个静态类,它冲Internet域名系统(DNS)检索关于特定主机的信息。在IPHostEntry类的实现中返回来自DNS查询的主机信息。如果指定的主机在DNS中有多个入库,则IPHostEntry包含多个IP地址和别名,常用方法如下:
| 序号 | 方法 | 说明 |
| 1 | BeginGetHostAddresses | 异步返回指定主机的Internet协议地址(IP地址) |
| 2 | BeginGetHostByName | 开始异步请求关于指定DNS主机名的IPHostEntry信息 |
| 3 | EndGetHostAddresses | 结束对DNS主机IP地址的异步请求 |
| 4 | EndGetHostByName | 结束对DNS主机名的异步请求 |
| 5 | EndGetHostEntry | 结束对DNS信息的异步请求 |
| 6 | GetHostAddress | 返回指定主机的Internet协议地址(IP地址) |
| 7 | GetHostByAddress | 获取IP地址的DNS主机信息 |
| 8 | GetHostByName | 获取指定DNS主机名的DNS信息 |
| 9 | GetHostEntry | 将主机名或IP地址解析为IPHostEntry实例 |
| 10 | GetHostName | 获取本地计算机的主机名 |
2.2 IPAddress类
IPAddress类包含计算机在IP网络上的地址,主要用来提供IP地址,常用字段、属性、方法如下:
| 序号 | 字段/属性/方法 | 字段/属性/方法名 | 说明 |
| 1 | 字段 | Any | 提供一个IP地址,指示服务器应侦听所有网络接口的上的客户端活动,此字段为只读 |
| 2 | 字段 | Broadcast | 提供IP广播地址,此字段为只读 |
| 3 | 字段 | Loopback | 提供IP环回地址,此字段为只读 |
| 4 | 属性 | Address | 网络协议地址(IP) |
| 5 | 属性 | AddressFamily | 获取IP地址的地址族 |
| 6 | 属性 | IsIPv6LinkLoacal | 获取地址是否为IPv6连接本地地址 |
| 7 | 属性 | IsIPv6SiteLoacal | 获取地址是否为IPv6站点本地地址 |
| 8 | 方法 | GetAddressBytes | 已字节数组形式提供IPAddress的副本 |
| 9 | 方法 | Pares | 将IP地址字符串转换为IPAddress实例 |
| 10 | 方法 | TryPares | 确定字符串是否为有效的IP地址 |
2.3 IPHostEntry类
IPHostEntry类用来为Internet主机地址信息提供容器类,常用属性如下:
| 序号 | 属性 | 说明 |
| 1 | AddressList | 获取或设置与主机关联的IP地址列表 |
| 2 | Aliases | 获取或这只与主机关联的别名列表 |
| 3 | HostName | 获取或设置主机的DNS名称 |
3. TCP程序设计
TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。在C#中,TCP程序设计指的是利用Socket类、TcpClient类和TcpListener类编写的网络通信程序,这三个类都位于System.NET.Sockets命名空间中。利用TCP协议进行通信的两个应用程序是由主次之分的,要给称为服务器端,另一个称为客户端。
3.1 Soket类
Socket类主要用于管理连接,实现Berkeley通信端套接字接口,同时它还定义了绑定、连接网络端点即传输数据所需要的各种方法,提供处理端点连接传输等细节所需要的功能。
TcpClient和UpdClient等类在内部使用Socket类,Socket类的常用属性如下:
| 序号 | 属性 | 说明 |
| 1 | AddressFamily | 获取Socket的地址族 |
| 2 | Available | 获取已经从网络接收且可供读取的数据量 |
| 3 | Connected | 获取一个值,该值只是Socket是在上次Send还是Receive操作是连接到远程主机 |
| 4 | Handle | 获取Socket的操作系统句柄 |
| 5 | LocalEndPoint | 获取本地终结点 |
| 6 | ProtocolType | 获取Socket的协议类型 |
| 7 | RemoteEndPoint | 获取远程终结点 |
| 8 | SendTimeout | 获取或设置一个值,该值指定之后同步Send调用将超时的时间长度 |
Socket类的常用方法如下
| 序号 | 方法 | 说明 |
| 1 | Accept | 为新连接创建新的Socket |
| 2 | BeginAccect | 开始一个异步操作来接受一个传入的连接尝试 |
| 3 | BeginConnect | 开始一个对远程主机连接的异步请求 |
| 4 | BeginDisconnect | 开始异步请求从远程终结点断开连接 |
| 5 | BeginReceive | 开始从连接的Socket中异步接收数据 |
| 6 | BeginSend | 将数据异步发送到连接的Socket |
| 7 | BeginSendFile | 将文件异步发送到连接的Socket |
| 8 | BeginSendTo | 向特定远程主机异步发送数据 |
| 9 | Close | 关闭Socket连接并释放所有关联的资源 |
| 10 | Connect | 建立与远程主机的连接 |
| 11 | Disconnect | 关闭套接字连接并允许重用套接字 |
| 12 | EndAccept | 异步接受传入的连接尝试 |
| 13 | EndConnect | 结束挂起的异步连接请求 |
| 14 | EndDisconnect | 结束挂起的异步断开连接请求 |
| 15 | EndSend | 结束挂起的异步发送 |
| 16 | EndSendFile | 结束挂起的文件异步发送 |
| 17 | EndSendTo | 结束挂起的向指定位置进行的异步发送 |
| 18 | Listen | 将Socket置于侦听状态 |
| 19 | Receive | 接受来自绑定的Socket的数据 |
| 20 | Send | 将数据发送到连接的Socket |
| 21 | SendFile | 将文件和可选数据异步发送到连接的Socket |
| 22 | SendTo | 将数据发送到特定终结点 |
| 23 | Shutdown | 禁用某Socket上发送和接收 |
3.2 TcpClient类和TcpListenner类
TcpClient类的常用属性及方法
| 序号 | 属性/方法 | 方法 | 说明 |
| 1 | 属性 | Available | 获取已经从网络接收且可提供读取的数据量 |
| 2 | 属性 | Client | 获取或设置基础Socket |
| 3 | 属性 | Connected | 获取一个值,该值指示TcpClient的基础Socket是否已连接到远程主机 |
| 4 | 属性 | ReceiveBufferSize | 获取或设置接收缓冲区的大小 |
| 5 | 属性 | ReceiveTimeout | 获取或设置在初始化一个读取操作后TcpClient等待接收数据的时间量 |
| 6 | 属性 | SendBufferSize | 获取或设置发送缓冲区的大小 |
| 7 | 属性 | SendTimeout | 获取或设置TcpClient等待发送操作成功完成的时间量 |
| 8 | 方法 | BeginConnect | 开始一个对远程主机连接的异步请求 |
| 9 | 方法 | Close | 释放此TcpClient实例,而不关闭基础连接 |
| 10 | 方法 | Connect | 使用指定主机名和端口号将客户端连接到TCP主机 |
| 11 | 方法 | EndConnect | 异步接受传入的连接尝试 |
| 12 | 方法 | GetStream | 返回用于发送和接收数据的NetworkStream |
TcpListenner类的常用属性及方法
| 序号 | 属性/方法 | 方法 | 说明 |
| 1 | 属性 | LocalEndpoint | 获取一个 EndPoint ,其中包含绑定到 Socket 的本地 IP 地址和端口号 |
| 2 | 属性 | Server | 获取基础网络Socket |
| 3 | 方法 | AcceptSocket/AcceptTcpClient | 接受挂起的连接请求 |
| 4 | 方法 | BeginAcceptSocket/BeginAcceptTcpClient | 开始一个异步操作来接受一个传入的连接尝试 |
| 5 | 方法 | EndAcceptSocket | 异步接受传入的连接尝试,并创建新的Socket来处理远程主机通信 |
| 6 | 方法 | EndAcceptTcpClient | 异步接受传入的连接尝试,并创建新的TcpClient来处理远程主机通信 |
| 7 | 方法 | Start | 开始侦听传入的连接请求 |
| 8 | 方法 | Stop | 关闭侦听器 |
例:服务器端代码
static void Main(string[] args)
{
int port = 888; //端口
TcpClient tcpClient = new TcpClient(); //创建TCP连接对象
IPAddress[] serverIP = Dns.GetHostAddresses("127.0.0.1"); //定义IP地址
IPAddress localAddress = serverIP[0]; //IP地址
TcpListener tcpListener = new TcpListener(localAddress, port);//监听套接字
tcpListener.Start(); //开始监听
Console.WriteLine("服务器启动成功,等待用用户接入..."); //输出消息
while(true)
{
try
{
//每接受一个客户端则生成一个TcpClient
tcpClient = tcpListener.AcceptTcpClient();
NetworkStream networkStream = tcpClient.GetStream(); //获取网络数据流
//定义数据流读取对象
BinaryReader reader = new BinaryReader(networkStream);
//定义流数据写入对象
BinaryWriter writer = new BinaryWriter(networkStream);
while (true)
{
try
{
string strReader = reader.ReadString(); //接收消息
//截取客户端消息
string[] strReaders = strReader.Split(new char[] { ' ' });
//输出接收的客户端IP地址
Console.WriteLine("有客户进入,客户IP:" + strReaders[0]);
//输出接收的消息
Console.WriteLine("来自客户的消息:" + strReaders[1]);
string strWriter = "我是服务器,欢迎进入"; //定义服务端要写入的消息
writer.Write(strWriter); //向对方发送消息
}
catch
{
break;
}
}
}
catch
{
break;
}
}
}
例:客户端代码
static void Main(string[] args)
{
//创建一个TcpClient对象,自动分配主机IP地址和端口号
TcpClient tcpClient = new TcpClient();
//连接服务器,其IP和端口号为127.0.0.1和888
tcpClient.Connect("127.0.0.1", 888);
//判断是否连接成功
if (tcpClient != null)
{
Console.WriteLine("连接服务器成功");
NetworkStream networkStream = tcpClient.GetStream(); //获取数据流
BinaryReader reader = new BinaryReader(networkStream); //定义数据流读取对象
BinaryWriter writer = new BinaryWriter(networkStream); //定义数据流写入对象
string Localip = "127.0.0.1"; //存储本机IP地址,默认127.0.0.1
IPAddress[] ips=Dns.GetHostAddresses(Dns.GetHostName());//获取所有IP地址
foreach (IPAddress ip in ips) {
if(!ip.IsIPv6SiteLocal) //如果不是本地站点的IPv6地址
Localip=ip.ToString(); //获取本机IP地址
}
writer.Write(Localip +" "+ "你好,我是洞幺"); //向服务器发送消息
string strReader = reader.ReadString(); //接收服务器发送的数据
Console.WriteLine("来自服务器的消息:" + strReader);
while (true)
{
try
{
Console.Write("请输入要发送的消息(输入exit退出):");
string input = Console.ReadLine();
if (input.ToLower() == "exit") break;
writer.Write(Localip + " "+input);
//接收服务器回复并输出
string response = reader.ReadString();
Console.WriteLine("服务器回复:" +response);
}
catch
{
break;
}
}
}
else
{
Console.WriteLine("连接服务器失败");
}
}
4. UPD程序设计
UPD(user datagram protocol)用户数据报协议,是网络信息传输的另一种形式,与TCP不同,信息传递更快,但不提供可靠的保证。
基本模式:
将数据打包,将数据报发往目的地址
接受别人发来的数据包,然后查看数据包
因为UPD是无连接传输协议,因此不需要再发送和接收数据前建立远程主机连接,但是可以使用下面的方法建立默认远程主机
·使用远程主机名和端口号作为参数创建UdpClient类的实现
·创建UdpClient类的实例,然后调用Connect方法
UdpClient类常用的属性方法如下:
| 序号 | 属性/方法 | 方法 | 说明 |
| 1 | 属性 | Available | 获取从网络接收的可读取的数据量 |
| 2 | 属性 | Client | 获取或设置基础网络Socket |
| 3 | 方法 | BeginReceive | 从远程主机异步接收数据报 |
| 4 | 方法 | BeginSend | 将数据报异步发送到远程主机 |
| 5 | 方法 | Close | 关闭UDP连接 |
| 6 | 方法 | Connect | 建立默认远程主机 |
| 7 | 方法 | EndReceive | 结束挂起的异步接收 |
| 8 | 方法 | EndSend | 结束挂起的异步发送 |
| 9 | 方法 | Receive | 返回已由远程主机发送的UDP数据报 |
| 10 | 方法 | Send | 将UDP数据报发送到远程主机 |
示例代码如下
更多推荐


所有评论(0)