网络是什么?
从远程服务器上获取数据
把本地数据上传到服务器上
在网络环境中,我们最感兴趣的两个名称空间是System.Net和System.Net.Sockets。
System.Net名称空间通常与较高层的操作有关,例如下载和上传文件,使用HTTP和其他协议进行Web请求等;
而System.Net.Sockets名称空间包含的类通常与较低层的操作有关。如果要直接使用套接字或TCP/IP之类的协议,这个名称空间中的类就非常有用。
System.Net命名空间
System.Net命名空间为当前网络上使用的多种协议提供了简单的编程接口,而它所包含的WebRequest类和WebResponse类形成了所谓的可插接式协议的基础。
可插接式协议是网络服务的一种实现,它使用户能够开发出使用Internet资源的应用程序,而不必考虑各种不同协议的具体细节。
Dns类
Dns类是一个静态类,它从Internet域名系统(Dns)检索关于特定主机的信息。在IPHostEntry类的实例中返回来自DNS查询的主机信息。如果指定的主机在DNS数据库中有多个入口,则IPHostEntry包含多个IP地址和别名。
| 方法 | 说明 |
|---|---|
| BeginGetHostAddresses | 异步返回指定主机的Internet协议(IP)地址 |
| BeginGetHostByName | 开始异步请求关于指定DNS主机名的IPHostEntry信息 |
| EndGetHostAddresses | 结束对DNS信息的异步请求 |
| EndGetHostByName | 结束对DNS信息的异步请求 |
| EndGetHostEntry | 结束对DNS信息的异步请求 |
| GetHostAddresses | 返回指定主机的Internet协议(IP)地址 |
| GetHostByAddresses | 获取IP地址的DNS主机信息 |
| GetHostByName | 获取指定DNS主机名的DNS信息 |
| GetHostEntry | 将主机名或IP地址解析为IPHostEntry实例 |
| GetHostName | 获取本地计算机的主机名 |
在Form窗体中添加4个TextBox控件和一个Button控件。TextBox控件分别用来输入主机地址和显示主机IP地址、本地主机名、DNS主机名。
private void button_Click(object sender, EventArgs e)
{
//判断是否输入了主机地址
if(TextBox1.Text == string.Empty)
{
MessageBox.Show("请输入主机地址");
}
else
{
textBox2.Text = string.Empty;
//获取指定主机的IP地址
IPAddress[] ips = Dns.GetHostAddresses(textBox1.Text);
foreach(IPAddress ip in ips)
{
textBox2.Text = ip.ToString();
}
//获取本机名
textBox3.Text = Dns.GetHostName();
//根据指定的主机名获取DNS信息
textBox4.Text = Dns.GetHostByName(Dns.GetHostName()).HostName;
}
}
IPAddress类
IPAddress类包含计算机在Ip网络上的地址,它主要用来提供网际协议(IP)地址。
| 字段、属性及方法 | 说明 |
|---|---|
| Any字段 | 提供一个IP地址,指示服务器应侦听所有网络接口上的客户端活动。该字段为只读。 |
| Broadcast字段 | 提供IP广播地址。该字段为只读。 |
| Loopback字段 | 提供IP环回地址。该字段为只读。 |
| None字段 | 提供指示不应使用任何网络接口的IP地址。该字段为只读。 |
| Address属性 | 网际协议(IP)地址 |
| AddressFamily属性 | 获取IP地址的地址族 |
| IsIPv6LinkLocal属性 | 获取地址是否IPv6链接本地地址 |
| IsIPv6Multicast属性 | 获取地址是否为IPv6多路广播全局地址 |
| IsIPv6SiteLocal属性 | 获取地址是否为IPv6站点本地地址 |
| ScopeId属性 | 获取或设置IPv6地址范围标识符 |
| GetAddressBytes方法 | 以字节数组形式提供IPAddress的副本 |
| IsLoopback方法 | 指示指定的IP地址是否是环回地址 |
| Parse方法 | 将IP地址字符串转换为IPAddress实例 |
| TryParse方法 | 确定字符串是否为有效的IP地址 |
IPEndPoint类
IPEndPoint类包含应用程序连接到主机上的服务所需的主机和本地或远程端口信息。通过组合服务的主机IP地址和端口号,IPEndPoint类形成到服务器的连接点,它主要用来将网络端点表示为IP地址和端口号。
| 字段即属性 | 说明 |
|---|---|
| MaxPort字段 | 指定可以分配给port属性的最大值。Maxport值设置为0x0000FFFF。该字段为只读。 |
| MinPort字段 | 可以分配给指定port属性的最小值。该字段为只读。 |
| Address属性 | 获取或设置终结点的IP地址 |
| AddressFamily属性 | 获取网际协议(IP)地址族 |
| Port属性 | 获取或设置终结点的端口号 |
WebClient类
WebClient类提供向URI标识的任何本地、Intranet或Internet资源发送数据以及从这些资源接收数据的公共方法。
| 属性及方法 | 说明 |
|---|---|
| BaseAddress属性 | 获取或设置WebClient发出请求的基URI |
| Encoding属性 | 获取或设置用于上传和下载字符串的Encoding |
| Headers属性 | 获取或设置与请求关联的报头名称/值对集合 |
| QueryString属性 | 获取或设置与请求关联的查询名称/值对集合 |
| ResponseHesders | 获取与响应关联的报头名称/值对集合 |
| DownloadData方法 | 以Byte数组形成通过指定的URI下载 |
| DownloadFile方法 | 将具有指定URI的资源下载到本地文件 |
| DownloadString方法 | 以String或URI形式下载指定的资源 |
| OpenRead方法 | 为从具有指定URI的资源下载的数据打开一个可读的流 |
| OpenWrite方法 | 打开一个流,以将数据写入具有制定URI的资源 |
| UploadData方法 | 将数据缓冲区上传到具有指定URI的资源 |
| UploadFile方法 | 将本地文件上传到具有指定URI的资源 |
| UploadString方法 | 将指定的字符串上传到指定的资源 |
| UploadValues方法 | 将名称/值集合上传到具有指定URI的资源 |
System.Net.Sockets命名空间
TcpClient类和TcpListener类
TcpClient类用于在同步阻止模式下通过网络连接、发送和接受流数据。为使TcpClient连接并交换数据,使用TcpProtocolType类创建的TcpListener实例或Socket实例必须侦听是否有传入的连接请求。
TcpListener类用于在阻止同步模式下侦听和接受传入的连接请求。可使用TcpClient类或Socket类来连接TcpListener,并且可以使用IPEndPoint、本地IP地址及端口号或者仅使用端口号来创建TcpListener实例对象。
TcpClient类的常用属性、方法
| 属性、方法 | 说明 |
|---|---|
| Available属性 | 获取已经从网络接收且可供读取的数据量 |
| Client属性 | 获取或设置基础Socket |
| Connected属性 | 获取一个值,该值指示TcpClient的基础Socket是否已连接到远程主机 |
| ReceiveBufferSize属性 | 获取或设置接收缓冲区的大小 |
| ReceiveTimeout属性 | 获取或设置在初始化一个读取操作以后TcpClient等待接收数据的时间量 |
| SendBufferSize属性 | 获取或设置发送缓冲区的大小 |
| SendTimeout属性 | 获取或设置TcpClient等待发送操作成功完成的时间量 |
| BeginConnect方法 | 开始一个对远程主机连接的异步请求 |
| Close方法 | 释放此TcpClient实例,而不关闭基础连接 |
| Connect方法 | 使用指定的主机名和端口号将客户端连接到TCP主机 |
| EndConnect方法 | 异步接收传入的连接尝试 |
| GetStream方法 | 返回用于发送和接收数据的NetworkStream |
TcpListener类的常用属性、方法
| 属性及方法 | 说明 |
|---|---|
| LocalEndpoint属性 | 获取当前TcpListener的基础EndPoint |
| Server属性 | 获取基础网络Socket |
| AcceptSocket/AcceptTcpClient | 接收挂起的连接请求 |
| BeginAcceptSocket/BeginAcceptTcpClient方法 | 开始一个异步操作来接收一个传入的连接尝试 |
| EndAcceptSocket方法 | 异步接收传入的连接尝试,并创建新的Socket来处理远程主机通信 |
| EndAcceptTcpClient方法 | 异步接收传入的连接尝试,并创建新的TcpClient来处理远程主机通信 |
| start方法 | 开始侦听传入的连接请求 |
| stop方法 | 关闭侦听器 |
UdpClient类
UdpClient类用于在阻止同步模式下发送和接收无连接UDP数据。因为UDp是无连接传输协议,所以不需要在发送和接收数据前建立远程主机连接,但可以使用下面两种方法之一来建立默认远程主机。
- 使用远程主机名和端口号作为参数创建UdpClient类的实例。
- 创建UdpClient类的实例,然后调用Connect方法。
| 属性及方法 | 说明 |
|---|---|
| Available属性 | 获取从网络接收的可供读取的数据量 |
| Client属性 | 获取或设置基础网络Socket |
| BeginReceive方法 | 从远程主机异步接收数据报 |
| BeginSend方法 | 将数据报异步发送到远程主机 |
| Close方法 | 关闭UDP连接 |
| Connect方法 | 建立默认远程主机 |
| EndReceive方法 | 结束挂起的异步接收 |
| EndSend方法 | 结束挂起的异步发送 |
| Receive方法 | 返回已由远程主机发送的UDP数据报 |
| Send方法 | 将UDP数据报发送到远程主机 |
Socket类
Socket类为网络通信提供了一套丰富的方法和属性,它主要用于管理连接,实现Berkeley通信端套接字接口。同时它还定义了绑定、连接网络端点及传输数据所需的各种烦方法,提供处理端点连接传输等细节所需的功能。
Socket类的常用属性及说明:
| 属性 | 说明 |
|---|---|
| AddressFamily | 获取Socket的地址族 |
| Available | 获取已经网络接收且可供读取的数据量 |
| Coonected | 获取一个值,该值指示Socket是在上次Send还是Receive操作时连接到远程主机 |
| Handle | 获取Socket的操作系统句柄 |
| LocalEndPoint | 获取本地终结点 |
| ProtocolType | 获取Socket的协议类型 |
| RemoteEndPoint | 获取远程终结点 |
| SendTimeout | 获取或设置一个值,该值指定之后同步Send调用将超时的时间长度 |
Socket类的常用方法及说明:
| 方法 | 说明 |
|---|---|
| Accpet | 为新建连接创建新的Socket |
| BeginAccept | 开始一个异步操作来接受一个传入的连接尝试 |
| BeginDisconnect | 开始异步请求从远程终结点断开连接 |
| BeginReceive | 开始从连接的Socket中异步接收数据 |
| BeginSend | 将数据异步发送到连接的Socket |
| BeginSendTo | 向特定远程主机异步发送数据 |
| Close | 关闭Socket连接并释放所有关联的资源 |
| Connect | 建立与远程主机的连接 |
| DisConnect | 关闭套接字连接并允许重用套接字 |
| EndAccept | 异步接受传入的连接尝试 |
| EndConnect | 结束挂起的异步连接请求 |
| EndDisConnect | 结束挂起的异步断开连接请求 |
| EndReceive | 结束挂起的异步读取 |
| EndSend | 结束挂起的异步发送 |
| EndSendTo | 结束挂起的、向指定位置进行的异步发送 |
| Listen | 将Socket置于侦听状态 |
| Receive | 接受来自绑定的Socket的数据 |
| Send | 将数据发送到连接的Socket |
| SendTo | 将数据发送到特定结点 |
TCP
开发TCPServer服务器端
namespace TCP_Server
{
public class Class1
{
static void Main(string[] args)
{
Socket tcpServer = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
IPAddress ipAddress = new IPAddress(new byte[]{10,20,1,125});
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress,8001);
tcpServer.Bind(ipEndPoint);
tcpServer.Listen(100);
Console.WriteLine("开始工作了...");
Socket client = tcpServer.Accept();
Console.WriteLine("一个客户端接过来了");
}
}
}
开发TCPClient客户端连接服务器
namespace TCP_Client
{
class Program
{
static void Main(string[] args)
{
Socket tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipAddress = new IPAddress(new byte[] { 10, 20, 1, 125 });
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 8001);
tcpClient.Connect(ipEndPoint);
Console.WriteLine("连接上服务器端了");
}
}
}
先启动服务器端,在启动客户端。
服务器与客户端相互传递信息
创建服务器端:TcpServer
namespace TCP_Server
{
class Server
{
static void Main(string[] args)
{
Socket tcpServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipAddress = new IPAddress(new byte[] { 10, 20, 1, 125 });
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 8001);
tcpServer.Bind(ipEndPoint);
tcpServer.Listen(100);
Console.WriteLine("开始工作了...");
Socket client = tcpServer.Accept();
Console.WriteLine("一个客户端接过来了");
//接收
byte[] data = new byte[1024];
int length = client.Receive(data);
//将字节码转换成字符串
string message = Encoding.UTF8.GetString(data, 0, length);
Console.WriteLine("接收到了客户端的消息;" + message);
client.Send(Encoding.UTF8.GetBytes("服务端发到客户端"));
client.Close();
tcpServer.Close();
}
}
}
创建客户端:TcpClient
namespace TCP_Client
{
class Client
{
static void Main(string[] args)
{
Socket tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipAddress = new IPAddress(new byte[] { 10, 20, 1, 125 });
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 8001);
tcpClient.Connect(ipEndPoint);
Console.WriteLine("连接上服务器端了");
string message = "我上线了";
//转换成字节并发送
tcpClient.Send(Encoding.UTF8.GetBytes(message));
//接收
byte[] data = new byte[1024];
int length = tcpClient.Receive(data);
Console.WriteLine("接收到了服务器端的消息;" + Encoding.UTF8.GetString(data, 0, length));
tcpClient.Close();
}
}
}
UDP
开发udpServer服务器端
namespace UDP_Server
{
public class Class1
{
static void Main(string[] args)
{
Socket udpServer = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
IPAddress ipAddress = new IPAddress(new byte[]{10,20,1,125});
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress,8001);
udpServer.Bind(ipEndPoint);
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 0);
EndPoint ep = (EndPoint)ipep;
byte[] data = new byte[1024];
int length = udpServer.ReceiveForm(data, ref ep);
Console.WriteLine("接收到数据:"+ Encoding.UTF8.GetString(data, 0, length));
udpServer.Close();
}
}
}
开发udpServer客户端
namespace UDP_Client
{
public class Class1
{
static void Main(string[] args)
{
Socket udpClient = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
IPAddress ipAddress = new IPAddress(new byte[]{10,20,1,125});
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress,8001);
byte[] data = Encoding.UTF8.GetBytes("你好,udp客户端上线了");
udpClient.SendTo(data, ipEndPoint);
udpClient.Close();
}
}
}
TCP与UDP的区别
1、基于连接与无连接
2、对系统资源的要求(TCP较多,UDP较少)
3、UDp程序结构简单
4、流模式与数据报模式
5、TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证










