一、C# .NET 网络编程相关类
IPAddress 类
用于表示一个 IP 地址,常用构造方法:
IPAddress address = IPAddress.Parse("192.168.1.1");
IPAddress 类还有其他的一些共用方法,具体可以在 IPAddress类 查询。
DNS 类
它是一个静态类,主要用途将主机名和电子邮件目标地址映射成 IP 地址,即域名解析功能。常用方法如下:
DNS 类还提供了异步的方法,具体可以参考 DNS 类 。
IPEndPoint 类
表示指定 IP 地址和端口号的组合,两个构造函数:
public IPEndPoint(long address, int port)
publicIPEndPoint(IPAddress address, int port)
属性:
Socket 类
Socket 类为网络通信提供了丰富的方法和属性。TcpClient、TCPListener 和 UDPClient 类建立在 Socket 类的基础上,可以实现传输控制协议(TCP)和用户数据报协议(UDP)服务。
异步 Socket 方法可以使用 NetworkStream 类提供的异步方法,具体用法可以参考NetworkStream 类。
二、Socket 编程
C# 套接字类原型:
public Socket(AddressFamily aF,SocketType sT,ProtocolType pT);
常用属性:
常用方法:
使用套接字的简单示例:基于 TCP 的应用程序
新建 Windows 控制台应用程序。
服务端程序:在 Main() 中编写业务逻辑,不要忘记添加命名空间。
-
Socket client;
-
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050); //创建 IPEndPoint 对象,表示接受任何端口 9050 的客户机地址
-
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // TCP
-
server.Bind(ipep); //绑定
-
server.Listen(20); //监听
-
Console.WriteLine("正在监听...");
-
while(true)
-
{
-
client = server.Accept(); //收到请求
-
if(client != null)
-
{
-
Console.WriteLine("客户机" + client.RemoteEndPoint + "连接到服务器");
-
string data = "hello client";
-
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data); //将 string 转化为 byte 数组
-
server.Send(msg); //向客户端发生数据
-
server.Close();
-
break;
-
}
-
}
客户端程序:
-
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // TCP
-
IPAddress adr = IPAddress.Parse("127.0.0.1"); //绑定到 127.0.0.1
-
IPEndPoint iep = new IPEndPoint(adr, 9050); //绑定到 9050 端口
-
client.Connect(iep); //连接服务端
-
byte[] buffer = new byte[1024];
-
int i;
-
if((i = client.Receive(buffer)) != 0)
-
{
-
Console.WriteLine("连接上服务器,正在接收数据...");
-
string data = System.Text.Encoding.ASCII.GetString(buffer, 0, i);
-
Console.WriteLine(data);
-
client.Close();
-
}
必须首先执行服务端程序,在执行客户端程序。运行结果:
服务端:
客户端:
上面的例子有很多不足,例如只能处理单个客户端的请求,没有加入异常处理机制,同时阻塞的套接字也会影响程序的并行度和效率。
三、TcpClient 与 TcpListener 类
它们是对 Socket 进行了封装,这两个类会自己创建 Socket 对象。使用起来比直接使用 Socket 要方便一点。
服务器程序:
-
static void Main(string[] args)
-
{
-
try
-
{
-
//创建 TcpListener 对象,监听端口 9050
-
TcpListener listener = new TcpListener(9050);
-
listener.Start();
-
Console.WriteLine("正在监听...");
-
//接受一个连接请求
-
TcpClient client = listener.AcceptTcpClient();
-
NetworkStream stream = client.GetStream(); //这是一个网络流,从这个网络流可以去的从客户端发来的数据
-
while (true)
-
{
-
byte[] data = new byte[1024];
-
int length = stream.Read(data, 0, 1024);
-
string message = Encoding.UTF8.GetString(data, 0, length);
-
Console.WriteLine("收到信息:" + message);
-
}
-
stream.Close();
-
client.Close();
-
listener.Stop();//停止监听
-
Console.ReadLine();
-
}
-
catch (Exception ex)
-
{
-
//输出异常信息
-
Console.WriteLine(ex.ToString());
-
Console.ReadLine();
-
}
-
finally
-
{ }
-
}
-
}
客户端程序:
-
static void Main(string[] args)
-
{
-
try
-
{
-
//建立 TcpClient 对象,并连接到端口 9060 的 localhost
-
TcpClient tcpClient = new TcpClient("127.0.0.1", 9060);
-
NetworkStream stream = tcpClient.GetStream();//通过网络流进行数据的交换
-
//read来读取数据,write用来写入数据就是发送数据
-
byte[] data = new byte[1024];
-
stream.Read(data, 0, data.Length);
-
Console.WriteLine("收到数据" + Encoding.ASCII.GetString(data));
-
stream.Close();
-
tcpClient.Close();
-
Console.ReadLine();
-
}
-
catch (Exception ex)
-
{
-
Console.WriteLine(ex.ToString());
-
Console.ReadLine();
-
}
-
finally
-
{ }
-
}
四、UdpClient 类
TCP 与 UDP 协议对比:
- TCP 是面向连接的协议,UDP 为无连接协议;
- TCP 只支持一对一通信,而 UDP 支持一对多通信;
- TCP 基于流,没有消息边界,而 UDP 基于数据报,有消息边界。