开放的编程资料库

当前位置:我爱分享网 > C#教程 > 正文

C#网络

在本文中,我们展示了如何使用C#创建基本的网络程序。

System.Net命名空间为当今网络上使用的许多协​​议提供了一个简单的编程接口。

C#URI

Uri提供统一资源标识符(URI)的对象表示以及对URI各部分的轻松访问。

var resource = "http://webcode.me:80/";
var resource2 = "http://webcode.me/index.html";
var resource3 = "http://www.webcode.me/name=Peter&age=23";

var path = new Uri(resource);
var path2 = new Uri(resource2);
var path3 = new Uri(resource3);

Console.WriteLine(path.Port);
Console.WriteLine(path.Host);
Console.WriteLine(path.Authority);
Console.WriteLine(path.LocalPath);
Console.WriteLine(path.Scheme);

Console.WriteLine("-----------------------");

Console.WriteLine(path2.Port);
Console.WriteLine(path2.LocalPath);

Console.WriteLine("-----------------------");

Console.WriteLine(path3.Authority);
Console.WriteLine(path3.PathAndQuery);
Console.WriteLine(path3.Query);
Console.WriteLine(path3.AbsolutePath);
Console.WriteLine(path3.AbsoluteUri);

在此示例中,我们使用Uri类。

var resource = "http://webcode.me:80/";
var resource2 = "http://webcode.me/index.html";
var resource3 = "http://www.webcode.me/name=Peter&age=23";

我们定义了三个资源路径。

var path = new Uri(resource);
var path2 = new Uri(resource2);
var path3 = new Uri(resource3);

根据路径,我们创建网络资源。

Console.WriteLine(path.Port);
Console.WriteLine(path.Host);
Console.WriteLine(path.Authority);
Console.WriteLine(path.LocalPath);
Console.WriteLine(path.Scheme);

这里我们打印一个Uri的各个部分。

$ dotnet run
80
webcode.me
webcode.me
/
http
-----------------------
80
/index.html
-----------------------
www.webcode.me
/name=Peter&age=23

/name=Peter&age=23
http://www.webcode.me/name=Peter&age=23

C#UriBuilder

UriBuilder提供了一种方便的方法来修改Uri实例的内容,而无需为每次修改创建新的Uri实例。

using System.Net;

var uriBuilder = new UriBuilder();
uriBuilder.Scheme = "http";
uriBuilder.Host = "webcode.me";
uriBuilder.Path = "/";

Uri uri = uriBuilder.Uri;

WebRequest request = WebRequest.Create(uri);
using WebResponse response = request.GetResponse();

var headers = response.Headers;
Console.WriteLine(headers);

该示例使用UriBuilder构建一个Uri,并对资源发出一个简单的GET请求。

var uriBuilder = new UriBuilder();
uriBuilder.Scheme = "http";
uriBuilder.Host = "webcode.me";
uriBuilder.Path = "/";

Uri uri = uriBuilder.Uri;

我们使用UriBuilder构建Uri

WebRequest request = WebRequest.Create(uri);

我们使用WebRequest创建对Uri的网络请求。

using WebResponse response = request.GetResponse();

使用GetResponse方法,我们向Uri指定的资源发出同步请求。

var headers = response.Headers;
Console.WriteLine(headers);

从响应中,我们获取标头并将它们打印到控制台。

$ dotnet run
Server: nginx/1.6.2
Date: Wed, 10 Feb 2021 12:42:16 GMT
Connection: keep-alive
ETag: "5d32ffc5-15c"
Access-Control-Allow-Origin: *
Accept-Ranges: bytes
Content-Type: text/html
Content-Length: 348
Last-Modified: Sat, 20 Jul 2019 11:49:25 GMT

我们看到服务器响应我们请求的标头。

C#主机名

Dns.GetHostName方法获取本地计算机的主机名。

using System.Net;

var hostName = Dns.GetHostName();
Console.WriteLine($"Hostname: {hostName}");

该程序打印出我们本地计算机的主机名。

$ dotnet run
Hostname: LAPTOP-OBLOFB9J

C#Dns.GetHostAddresses

Dns.GetHostAddresses返回一个IPAddress类型的数组,其中包含主机的IP地址。

using System.Net;

var hostname = "something.com";

IPAddress[] addresses = Dns.GetHostAddresses(hostname);

foreach (IPAddress address in addresses)
{
    Console.WriteLine($"{address}");
}

该示例打印网页的所有IP地址。

$ dotnet run
2606:4700:3033::ac43:b7a8
2606:4700:3031::6815:3bce
172.67.183.168
104.21.59.206

C#GetHostEntry

使用Dns.GetHostEntry方法,我们可以根据主机名确定IP地址。

using System.Net;

var name = "wikipedia.org";
IPHostEntry host = Dns.GetHostEntry(name);
var addresses = host.AddressList;

foreach (var address in addresses)
{
    Console.WriteLine($"{address}");
}

该示例打印了wikipedia.org网站的IP地址。

var addresses = host.AddressList;

AddressList属性包含与主机关联的IP地址列表。

$ dotnet run
2620:0:862:ed1a::1
91.198.174.192

输出由IPv6和IPv4地址组成。

C#平

Ping是一种网络管理实用程序,用于测试Internet协议(IP)网络上主机的可用性。Ping通过向目标主机发送Internet控制消息协议(ICMP)回显请求数据包并等待ICMP回显回复来工作。该程序报告错误、数据包丢失和结果的统计摘要。

.NET包含用于发送ping请求的Ping类。Ping类使用PingReply类的实例来返回有关操作的信息并接收回复。

using System.Net.NetworkInformation;

using var ping = new Ping();

PingReply reply = ping.Send("192.168.0.23", 100);

if (reply.Status == IPStatus.Success)
{
    var msg = @$"Status: {reply.Status}
IP Address:{reply.Address}
Time:{reply.RoundtripTime}ms";
    Console.WriteLine(msg);
}
else
{
    Console.WriteLine(reply.Status);
}

我们向本地lan上的主机发送Ping请求。

PingReply reply = ping.Send("192.168.0.23", 100);

Send方法尝试发送ICMP回显消息。第二个参数是超时时间。

$ dotnet run
Status: Success
IP Address:192.168.0.23
Time:4ms

C#套接字

在编程中,套接字是网络上运行的两个程序之间通信的端点。套接字用于在客户端程序和服务器程序之间创建连接。

System.Net.Sockets.Socket类实现了Berkeley套接字接口。

using System.Text;
using System.Net;
using System.Net.Sockets;

string server = "webcode.me";
int port = 80;

var request = $"GET / HTTP/1.1\r\nHost: {server}\r\nConnection: Close\r\n\r\n";

Byte[] requestBytes = Encoding.ASCII.GetBytes(request);
Byte[] bytesReceived = new Byte[256];

IPHostEntry hostEntry = Dns.GetHostEntry(server);

var ipe = new IPEndPoint(hostEntry.AddressList[0], port);
using var socket = new Socket(AddressFamily.InterNetwork,
    SocketType.Stream, ProtocolType.Tcp);

socket.Connect(ipe);

if (socket.Connected)
{
    Console.WriteLine("Connection established");
}
else
{
    Console.WriteLine("Connection failed");
    return;
}

socket.Send(requestBytes, requestBytes.Length, 0);

int bytes = 0;
var sb = new StringBuilder();

do
{

    bytes = socket.Receive(bytesReceived, bytesReceived.Length, 0);
    sb.Append(Encoding.ASCII.GetString(bytesReceived, 0, bytes));
} while (bytes > 0);

Console.WriteLine(sb.ToString());

该示例使用Socket类将数据发送到HTTP服务器并接收响应。此示例会阻塞,直到接收到整个页面。请注意,套接字编程是低级的。HttpWebRequestHttpClient等类抽象出这些低级细节。

string server = "webcode.me";
int port = 80;

我们定义服务器和端口。

var request = $"GET / HTTP/1.1\r\nHost: {server}\r\nConnection: Close\r\n\r\n";

我们定义了一个GET请求。GET请求使用GET命令发出,后跟资源URL和HTTP协议版本。请注意,\r\n字符是通信过程的必需部分。详细信息在RFC7231文档中进行了描述。

Byte[] requestBytes = Encoding.ASCII.GetBytes(request);

我们将请求的文本数据转换为字节。

Byte[] bytesReceived = new Byte[256];

此字节数组用于存储来自服务器的数据。

IPHostEntry hostEntry = Dns.GetHostEntry(server);

通过Dns.GetHostEntry我们可以找到域名的IP地址。

var ipe = new IPEndPoint(hostEntry.AddressList[0], port);

我们创建一个IPEndPoint;它是一个网络端点,由IP地址和端口号组成。IP地址是从AddressList属性中检索的。

using var socket = new Socket(AddressFamily.InterNetwork, 
    SocketType.Stream, ProtocolType.Tcp);

一个新的TCP套接字被创建。AddressFamily.InterNetwork指定我们使用IPv4地址。SocketType.Stream提供可靠的、双向的、基于连接的字节流。ProtocolType.Tcp确定协议类型。

socket.Connect(ipe);

我们使用Connect方法连接到具有给定IPEndPoint的网络端点。

if (socket.Connected)
{
    Console.WriteLine("Connection established");
}
else
{
    Console.WriteLine("Connection failed");
    return;
}

我们检查是否已成功连接。

socket.Send(requestBytes, requestBytes.Length, 0);

我们使用Send方法向服务器发送请求。

do
{

    bytes = socket.Receive(bytesReceived, bytesReceived.Length, 0);
    sb.Append(Encoding.ASCII.GetString(bytesReceived, 0, bytes));
} while (bytes > 0);

我们使用Receive方法从套接字中获取数据。我们使用GetString方法将字节转换为文本,并将文本数据添加到StringBuilder中。

Console.WriteLine(sb.ToString());

最后将文本数据写入控制台。

C#UdpClient

UdpClient提供用户数据报协议(UDP)网络服务。它包含以阻塞同步模式发送和接收无连接UDP数据报的方法。我们不需要在发送和接收数据之前建立远程主机连接,因为UDP是一种无连接传输协议,

出于安全考虑,大多数公共服务器不再提供回显服务。为了测试示例,我们需要在本地lan上设置服务器并启用xinetd(Debian)或inetd(FreeBSD)守护程序。

using System.Text;
using System.Net;
using System.Net.Sockets;

UdpClient udpClient = new UdpClient("core9", 7);
Byte[] data = Encoding.ASCII.GetBytes("Hello there");
udpClient.Send(data, data.Length);

IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);

Byte[] received = udpClient.Receive(ref RemoteIpEndPoint);
string output = Encoding.ASCII.GetString(received);

Console.WriteLine(output);

udpClient.Close();

该示例将消息发送到回显服务。这是一个用于测试目的的简单服务。echo服务在端口7上侦听。请注意,该服务可以在TCP或UDP上运行。

$ dotnet run
Hello there

我们发送的消息被回显给我们。

C#客户端

TcpClient类使用TCP从Internet资源请求数据。TcpClient抽象了创建Socket以通过TCP请求和接收数据的底层细节。

由于与远程设备的连接表示为流,因此可以使用.NET流处理技术读取和写入数据。

using System.Text;
using System.Net.Sockets;

using var client = new TcpClient();

var hostname = "webcode.me";
client.Connect(hostname, 80);

using NetworkStream networkStream = client.GetStream();
networkStream.ReadTimeout = 2000;

var message = @"GET / HTTP/1.1
Accept: text/html, charset=utf-8
Accept-Language: en-US
User-Agent: Console app
Connection: close
Host: webcode.me" + "\r\n\r\n";

using var reader = new StreamReader(networkStream, Encoding.UTF8);
byte[] bytes = Encoding.UTF8.GetBytes(message);

networkStream.Write(bytes, 0, bytes.Length);
Console.WriteLine(reader.ReadToEnd());

该示例使用TcpClient创建一个GET请求。

using var client = new TcpClient();

var hostname = "webcode.me";
client.Connect(hostname, 80);

一个TCP客户端被创建。我们使用Connect方法连接到远程主机。

using NetworkStream networkStream = client.GetStream();
networkStream.ReadTimeout = 2000;

使用GetStream方法,我们获取网络流。我们将超时设置为两秒。

var message = @"GET / HTTP/1.1
Accept: text/html, charset=utf-8
Accept-Language: en-US
User-Agent: Console app
Connection: close
Host: webcode.me" + "\r\n\r\n";

我们构建GET请求消息。不支持持久连接的HTTP/1.1应用程序必须在每条消息中包含close连接选项。

using var reader = new StreamReader(networkStream, Encoding.UTF8);
byte[] bytes = Encoding.UTF8.GetBytes(message);

对于来自服务器的响应,我们创建了一个StreamReader。我们使用GetBytes方法将文本数据转换为字节。

networkStream.Write(bytes, 0, bytes.Length);

我们使用Write方法将消息写入网络流。

Console.WriteLine(reader.ReadToEnd());

我们使用ReadToEnd方法读取响应。

C#FtpWebRequest

FtpWebRequest实现文件传输协议(FTP)客户端。

using System.Net;

string uri = "ftp://192.168.0.21";

FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(uri);
ftpRequest.Credentials = new NetworkCredential("user7", "s$cret");
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;

using FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
using var streamReader = new StreamReader(response.GetResponseStream());

var content = new List<string>();

string line = streamReader.ReadLine();
while (!string.IsNullOrEmpty(line))
{
    content.Add(line);
    line = streamReader.ReadLine();
}

foreach (var el in content)
{
    Console.WriteLine(el);
}

该示例列出了FTP目录中的内容。

string uri = "ftp://192.168.0.21";

这是本地FTP服务器上的URL路径。

FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(uri);

根据URI,我们创建FtpWebRequest

ftpRequest.Credentials = new NetworkCredential("user7", "s$cret");
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;

我们提供凭据和FTP方法;我们将列出内容或目录。

using FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
using var streamReader = new StreamReader(response.GetResponseStream());

我们得到一个响应并创建一个流阅读器来读取它。

var content = new List<string>();

string line = streamReader.ReadLine();
while (!string.IsNullOrEmpty(line))
{
    content.Add(line);
    line = streamReader.ReadLine();
}

数据被读入列表。

foreach (var el in content)
{
    Console.WriteLine(el);
}

最后,内容打印到控制台。

C#SmtpClient

SmtpClient允许应用程序使用简单邮件传输协议(SMTP)发送电子邮件。

请注意,该类已标记为过时,建议使用MailKit库来处理电子邮件。

using System.Net.Mail;

var client = new SmtpClient("core9", 25);

using var msg = new MailMessage();
msg.From = new MailAddress("john.doe@example.com");
msg.Subject = "Hello";

msg.Body = "hello there";

msg.To.Add(new MailAddress("root@core9"));
client.Send(msg);

该示例向本地网络上的服务器发送一封简单的邮件。

C#HttpClient

HttpClient是一个基类,用于从URI标识的资源发送HTTP请求和接收HTTP响应。

using var client = new HttpClient();

var result = await client.GetAsync("http://webcode.me");
Console.WriteLine(result.StatusCode);

该示例创建了一个对小型网站的GET请求。我们得到请求的状态码。

using var client = new HttpClient();

创建了一个新的HttpClient

var result = await client.GetAsync("http://webcode.me");

GetAsync方法将GET请求作为异步操作发送到指定的Uri。await运算符暂停对封闭异步方法的计算,直到异步操作完成。当异步操作完成时,await运算符返回操作结果(如果有)。

$ dotnet run
OK

我们得到200OK状态码;网站上线了。

C#HttpListener

HttpListener是一个简单的、以编程方式控制的HTTP协议侦听器。

using System.Net;
using System.Text;

using var listener = new HttpListener();
listener.Prefixes.Add("http://localhost:8001/");

listener.Start();

Console.WriteLine("Listening on port 8001...");

while (true)
{
    HttpListenerContext context = listener.GetContext();
    HttpListenerRequest req = context.Request;

    using Stream ris = req.InputStream;
    using StreamReader sr = new StreamReader(ris, Encoding.UTF8);
    string doc = sr.ReadToEnd();

    Console.WriteLine($"Received request for {req.Url}");
    Console.WriteLine(doc);

    HttpListenerResponse resp = context.Response;
    
    string data = "Hello there!";
    byte[] buffer = Encoding.UTF8.GetBytes(data);
    resp.ContentLength64 = buffer.Length;

    Stream ros = resp.OutputStream;
    ros.Write(buffer, 0, buffer.Length);
    
    ros.Close();
}

该示例创建了一个简单的HTTP服务器。

using var listener = new HttpListener();
listener.Prefixes.Add("http://localhost:8001/");

listener.Start();

我们创建一个侦听端口8001的侦听器。

HttpListenerContext context = listener.GetContext();
HttpListenerRequest req = context.Request;

使用GetContext,我们等待传入请求并在收到请求时返回。

using Stream ris = req.InputStream;
using StreamReader sr = new StreamReader(ris, Encoding.UTF8);
string doc = sr.ReadToEnd();

Console.WriteLine($"Received request for {req.Url}");
Console.WriteLine(doc);

服务器将请求记录到终端。

HttpListenerResponse resp = context.Response;

string data = "Hello there!";
byte[] buffer = Encoding.UTF8.GetBytes(data);
resp.ContentLength64 = buffer.Length;

我们构建响应对象。

Stream ros = resp.OutputStream;
ros.Write(buffer, 0, buffer.Length);

服务器使用Write将数据写入响应输出流。

在本文中,我们使用C#创建了一些基本的网络程序。

列出所有C#教程。

未经允许不得转载:我爱分享网 » C#网络

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏