中企業(yè)網(wǎng)站建設(shè)哪里做網(wǎng)站便宜
在現(xiàn)今軟件開發(fā)中,網(wǎng)絡(luò)編程是非常重要的一部分,本文簡(jiǎn)要介紹下網(wǎng)絡(luò)編程的概念和實(shí)踐。
C#網(wǎng)絡(luò)編程的主要內(nèi)容包括以下幾個(gè)方面?:
:
上圖引用大佬的圖,大家也關(guān)注一下,有技術(shù)有品質(zhì),有國(guó)有家,情懷滿滿的楊老師(不得不去仰慕一番哈哈)
https://blog.csdn.net/Eastmount/article/details/9321153
1. 底層網(wǎng)絡(luò)協(xié)議類?
如NetworkStream、TcpClient與TcpListener、UdpClient等,這些類提供了更底層的網(wǎng)絡(luò)操作接口,適用于需要直接控制網(wǎng)絡(luò)連接和數(shù)據(jù)處理的情況?
1. TCP 通信
使用 TcpListener 和 TcpClient 進(jìn)行 通訊
- TCP 服務(wù)器端示例
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;class TcpServerExample
{static async Task Main(string[] args){// 創(chuàng)建一個(gè) TCP/IP 套接字TcpListener listener = new TcpListener(IPAddress.Any, 13000);listener.Start();Console.WriteLine("Server started. Waiting for connections...");while (true){// 接受傳入連接TcpClient client = await listener.AcceptTcpClientAsync();Console.WriteLine("Client connected.");// 處理客戶端請(qǐng)求_ = HandleClient(client);}}static async Task HandleClient(TcpClient client){try{NetworkStream stream = client.GetStream();// 接收數(shù)據(jù)byte[] buffer = new byte[256];int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);string request = Encoding.ASCII.GetString(buffer, 0, bytesRead);Console.WriteLine("Received: " + request);// 發(fā)送響應(yīng)string response = "Hello, Client!";byte[] responseData = Encoding.ASCII.GetBytes(response);await stream.WriteAsync(responseData, 0, responseData.Length);Console.WriteLine("Sent: " + response);// 關(guān)閉連接client.Close();}catch (Exception ex){Console.WriteLine("Error: " + ex.Message);}}
}
- TCP 客戶端示例
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;class TcpClientExample
{static async Task Main(string[] args){try{// 創(chuàng)建一個(gè) TCP/IP 套接字TcpClient client = new TcpClient();await client.ConnectAsync("127.0.0.1", 13000);Console.WriteLine("Connected to server.");NetworkStream stream = client.GetStream();// 發(fā)送數(shù)據(jù)string message = "Hello, Server!";byte[] data = Encoding.ASCII.GetBytes(message);await stream.WriteAsync(data, 0, data.Length);Console.WriteLine("Sent: " + message);// 接收響應(yīng)byte[] buffer = new byte[256];int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);string response = Encoding.ASCII.GetString(buffer, 0, bytesRead);Console.WriteLine("Received: " + response);// 關(guān)閉連接client.Close();}catch (Exception e){Console.WriteLine("Error: " + e.Message);}}
}
2. UDP 通信
使用 UdpClient 進(jìn)行通訊
- UDP 服務(wù)器端示例
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;class UdpServerExample
{static async Task Main(string[] args){// 創(chuàng)建一個(gè) UDP/IP 套接字UdpClient listener = new UdpClient(11000);IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);Console.WriteLine("UDP Server started. Listening on port 11000...");while (true){// 接收數(shù)據(jù)byte[] buffer = await listener.ReceiveAsync();string request = Encoding.ASCII.GetString(buffer);Console.WriteLine("Received: " + request + " from " + remoteEndPoint.ToString());// 發(fā)送響應(yīng)string response = "Hello, Client!";byte[] responseData = Encoding.ASCII.GetBytes(response);await listener.SendAsync(responseData, responseData.Length, remoteEndPoint);Console.WriteLine("Sent: " + response);}}
}
- UDP 客戶端示例
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;class UdpClientExample
{static async Task Main(string[] args){try{// 創(chuàng)建一個(gè) UDP/IP 套接字UdpClient client = new UdpClient();IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000);// 發(fā)送數(shù)據(jù)string message = "Hello, Server!";byte[] data = Encoding.ASCII.GetBytes(message);await client.SendAsync(data, data.Length, remoteEP);Console.WriteLine("Sent: " + message);// 接收響應(yīng)UdpReceiveResult result = await client.ReceiveAsync();string response = Encoding.ASCII.GetString(result.Buffer);Console.WriteLine("Received: " + response + " from " + result.RemoteEndPoint.ToString());// 關(guān)閉連接client.Close();}catch (Exception e){Console.WriteLine("Error: " + e.Message);}}
}
3. 使用 NetworkStream 進(jìn)行自定義協(xié)議通信
NetworkStream 提供了一個(gè)流式接口,可以用于讀取和寫入網(wǎng)絡(luò)數(shù)據(jù)。以下是一個(gè)使用 NetworkStream 的示例,展示如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的自定義協(xié)議。
- 自定義協(xié)議服務(wù)器端示例
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;class CustomProtocolServerExample
{static async Task Main(string[] args){// 創(chuàng)建一個(gè) TCP/IP 套接字TcpListener listener = new TcpListener(IPAddress.Any, 13000);listener.Start();Console.WriteLine("Server started. Waiting for connections...");while (true){// 接受傳入連接TcpClient client = await listener.AcceptTcpClientAsync();Console.WriteLine("Client connected.");// 處理客戶端請(qǐng)求_ = HandleClient(client);}}static async Task HandleClient(TcpClient client){try{NetworkStream stream = client.GetStream();// 接收數(shù)據(jù)byte[] buffer = new byte[256];int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);string request = Encoding.ASCII.GetString(buffer, 0, bytesRead);Console.WriteLine("Received: " + request);// 解析自定義協(xié)議string[] parts = request.Split(':');if (parts.Length == 2 && parts[0] == "COMMAND"){string command = parts[1];Console.WriteLine("Command: " + command);// 處理命令并生成響應(yīng)string response = "ACK: Command received";byte[] responseData = Encoding.ASCII.GetBytes(response);await stream.WriteAsync(responseData, 0, responseData.Length);Console.WriteLine("Sent: " + response);}else{string response = "ERROR: Invalid command format";byte[] responseData = Encoding.ASCII.GetBytes(response);await stream.WriteAsync(responseData, 0, responseData.Length);Console.WriteLine("Sent: " + response);}// 關(guān)閉連接client.Close();}catch (Exception ex){Console.WriteLine("Error: " + ex.Message);}}
}
- 自定義協(xié)議客戶端示例
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;class CustomProtocolClientExample
{static async Task Main(string[] args){try{// 創(chuàng)建一個(gè) TCP/IP 套接字TcpClient client = new TcpClient();await client.ConnectAsync("127.0.0.1", 13000);Console.WriteLine("Connected to server.");NetworkStream stream = client.GetStream();// 發(fā)送自定義協(xié)議命令string message = "COMMAND:Hello";byte[] data = Encoding.ASCII.GetBytes(message);await stream.WriteAsync(data, 0, data.Length);Console.WriteLine("Sent: " + message);// 接收響應(yīng)byte[] buffer = new byte[256];int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);string response = Encoding.ASCII.GetString(buffer, 0, bytesRead);Console.WriteLine("Received: " + response);// 關(guān)閉連接client.Close();}catch (Exception e){Console.WriteLine("Error: " + e.Message);}}
}
2.Socket編程?
也就是我們常說的“套接字
”,Socket類在System.Net.Sockets
命名空間下,是最基本的網(wǎng)絡(luò)操作類,封裝了網(wǎng)絡(luò)連接的創(chuàng)建和關(guān)閉、數(shù)據(jù)的收發(fā)以及網(wǎng)絡(luò)狀態(tài)監(jiān)控等功能。通過Socket類,可以實(shí)現(xiàn)基于TCP
和UDP
的網(wǎng)絡(luò)通信?。
1. 使用 Socket 類進(jìn)行 TCP 通信
TCP 服務(wù)器端示例
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;class TcpServerExample
{static async Task Main(string[] args){// 創(chuàng)建一個(gè) TCP/IP 套接字Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// 綁定套接字到本地端口IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 13000);listener.Bind(localEndPoint);// 監(jiān)聽傳入連接listener.Listen(10);Console.WriteLine("Server started. Waiting for connections...");while (true){// 接受傳入連接Socket handler = await listener.AcceptAsync();Console.WriteLine("Client connected.");// 處理客戶端請(qǐng)求_ = HandleClient(handler);}}static async Task HandleClient(Socket handler){try{// 接收數(shù)據(jù)byte[] buffer = new byte[256];int bytesReceived = await handler.ReceiveAsync(new ArraySegment<byte>(buffer), SocketFlags.None);string request = Encoding.ASCII.GetString(buffer, 0, bytesReceived);Console.WriteLine("Received: " + request);// 發(fā)送響應(yīng)string response = "Hello, Client!";byte[] responseData = Encoding.ASCII.GetBytes(response);await handler.SendAsync(new ArraySegment<byte>(responseData), SocketFlags.None);Console.WriteLine("Sent: " + response);// 關(guān)閉連接handler.Shutdown(SocketShutdown.Both);handler.Close();}catch (Exception ex){Console.WriteLine("Error: " + ex.Message);}}
}
TCP 客戶端示例
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;class TcpClientExample
{static async Task Main(string[] args){try{// 創(chuàng)建一個(gè) TCP/IP 套接字Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// 連接到服務(wù)器IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 13000);await client.ConnectAsync(remoteEP);Console.WriteLine("Connected to server.");// 發(fā)送數(shù)據(jù)string message = "Hello, Server!";byte[] data = Encoding.ASCII.GetBytes(message);await client.SendAsync(new ArraySegment<byte>(data), SocketFlags.None);Console.WriteLine("Sent: " + message);// 接收響應(yīng)byte[] buffer = new byte[256];int bytesReceived = await client.ReceiveAsync(new ArraySegment<byte>(buffer), SocketFlags.None);string response = Encoding.ASCII.GetString(buffer, 0, bytesReceived);Console.WriteLine("Received: " + response);// 關(guān)閉連接client.Shutdown(SocketShutdown.Both);client.Close();}catch (Exception e){Console.WriteLine("Error: " + e.Message);}}
}
2. 使用 Socket 類進(jìn)行 UDP 通信
UDP 服務(wù)器端示例
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;class UdpServerExample
{static async Task Main(string[] args){// 創(chuàng)建一個(gè) UDP/IP 套接字Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);// 綁定套接字到本地端口IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 11000);listener.Bind(localEndPoint);Console.WriteLine("UDP Server started. Waiting for messages...");while (true){// 接收數(shù)據(jù)EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);byte[] buffer = new byte[256];int bytesReceived = await listener.ReceiveFromAsync(new ArraySegment<byte>(buffer), SocketFlags.None, remoteEndPoint);string request = Encoding.ASCII.GetString(buffer, 0, bytesReceived);Console.WriteLine("Received: " + request + " from " + remoteEndPoint.ToString());// 發(fā)送響應(yīng)string response = "Hello, Client!";byte[] responseData = Encoding.ASCII.GetBytes(response);await listener.SendToAsync(new ArraySegment<byte>(responseData), SocketFlags.None, remoteEndPoint);Console.WriteLine("Sent: " + response);}}
}
UDP 客戶端示例
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;class UdpClientExample
{static async Task Main(string[] args){try{// 創(chuàng)建一個(gè) UDP/IP 套接字Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);// 連接到服務(wù)器IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000);// 發(fā)送數(shù)據(jù)string message = "Hello, Server!";byte[] data = Encoding.ASCII.GetBytes(message);await client.SendToAsync(new ArraySegment<byte>(data), SocketFlags.None, remoteEP);Console.WriteLine("Sent: " + message);// 接收響應(yīng)EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);byte[] buffer = new byte[256];int bytesReceived = await client.ReceiveFromAsync(new ArraySegment<byte>(buffer), SocketFlags.None, remoteEndPoint);string response = Encoding.ASCII.GetString(buffer, 0, bytesReceived);Console.WriteLine("Received: " + response + " from " + remoteEndPoint.ToString());// 關(guān)閉連接client.Close();}catch (Exception e){Console.WriteLine("Error: " + e.Message);}}
}
注意事項(xiàng)
- 異常處理:使用 try-catch 塊來捕獲和處理異常。
- 資源管理:確保在使用完 Socket 后調(diào)用 Close 方法來釋放資源。
- 并發(fā)處理:對(duì)于服務(wù)器端,通常需要處理多個(gè)客戶端連接,可以使用多線程或異步編程來提高并發(fā)性能。
- 超時(shí)設(shè)置:對(duì)于 TCP 連接,可以設(shè)置超時(shí)時(shí)間來避免長(zhǎng)時(shí)間等待。
3.WebSocket通信?
WebSocket
是一種在單個(gè)TCP連接上進(jìn)行全雙工通訊的協(xié)議??梢允褂?System.Net.WebSockets
命名空間中的類來創(chuàng)建 WebSocket 服務(wù)器和客戶端。WebSocket通信常用于需要實(shí)時(shí)數(shù)據(jù)交換的應(yīng)用場(chǎng)景?,適用于需要實(shí)時(shí)數(shù)據(jù)交換的應(yīng)用場(chǎng)景,如實(shí)時(shí)聊天、在線游戲、股票行情等。
1.WebSocket 服務(wù)器端示例
以下是一個(gè)簡(jiǎn)單的 WebSocket 服務(wù)器端示例,使用 HttpListener
來處理 HTTP 請(qǐng)求并升級(jí)為 WebSocket 連接。
using System;
using System.IO;
using System.Net;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;class WebSocketServerExample
{static async Task Main(string[] args){HttpListener listener = new HttpListener();listener.Prefixes.Add("http://localhost:8080/");listener.Start();Console.WriteLine("WebSocket Server started. Listening on ws://localhost:8080/");while (true){HttpListenerContext context = await listener.GetContextAsync();if (context.Request.IsWebSocketRequest){HttpListenerWebSocketContext webSocketContext = await context.AcceptWebSocketAsync(null);_ = HandleWebSocketConnection(webSocketContext.WebSocket);}else{context.Response.StatusCode = (int)HttpStatusCode.BadRequest;context.Response.Close();}}}static async Task HandleWebSocketConnection(WebSocket webSocket){byte[] buffer = new byte[1024 * 4];WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);while (!result.CloseStatus.HasValue){string userMessage = Encoding.UTF8.GetString(new ArraySegment<byte>(buffer, 0, result.Count));Console.WriteLine("Received: " + userMessage);//來自客戶端:將消息回傳給客戶端byte[] responseBuffer = Encoding.UTF8.GetBytes("Echo: " + userMessage);await webSocket.SendAsync(new ArraySegment<byte>(responseBuffer), result.MessageType, result.EndOfMessage, CancellationToken.None);result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);}await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);webSocket.Dispose();}
}
2.WebSocket 客戶端示例
以下是一個(gè)簡(jiǎn)單的 WebSocket
客戶端示例,使用 ClientWebSocket
類來連接 WebSocket 服務(wù)器并進(jìn)行通信。
using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;class WebSocketClientExample
{static async Task Main(string[] args){using (ClientWebSocket webSocket = new ClientWebSocket()){Uri serverUri = new Uri("ws://localhost:8080/");await webSocket.ConnectAsync(serverUri, CancellationToken.None);Console.WriteLine("Connected to server.");byte[] buffer = new byte[1024 * 4];// 在單獨(dú)的任務(wù)中開始接收消息_ = ReceiveMessages(webSocket, buffer);// 向服務(wù)器發(fā)送消息while (webSocket.State == WebSocketState.Open){Console.Write("Enter message to send: ");string message = Console.ReadLine();byte[] messageBuffer = Encoding.UTF8.GetBytes(message);await webSocket.SendAsync(new ArraySegment<byte>(messageBuffer), WebSocketMessageType.Text, true, CancellationToken.None);}}}static async Task ReceiveMessages(ClientWebSocket webSocket, byte[] buffer){while (webSocket.State == WebSocketState.Open){WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);if (result.MessageType == WebSocketMessageType.Close){await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);break;}string receivedMessage = Encoding.UTF8.GetString(new ArraySegment<byte>(buffer, 0, result.Count));Console.WriteLine("Received: " + receivedMessage);}}
}
注意事項(xiàng)
- 異常處理:使用 try-catch 塊來捕獲和處理異常,特別是網(wǎng)絡(luò)相關(guān)的異常。
- 資源管理:確保在使用完 WebSocket 后調(diào)用 CloseAsync 和 Dispose 方法來釋放資源。
- 并發(fā)處理:對(duì)于服務(wù)器端,通常需要處理多個(gè)客戶端連接,可以使用多線程或異步編程來提高并發(fā)性能。
- 安全性:在生產(chǎn)環(huán)境中,建議使用
wss://(WebSocket Secure)
來加密通信,防止數(shù)據(jù)泄露。 - 心跳機(jī)制:為了保持連接活躍,可以定期發(fā)送心跳消息,防止中間設(shè)備關(guān)閉空閑連接。
4. HTTP請(qǐng)求?:
可以使用HttpClient、WebClient、HttpRequestMessage和HttpMessageHandler等類來發(fā)送HTTP請(qǐng)求。這些類提供了發(fā)送GET、POST等請(qǐng)求的方法,并支持異步操作和身份驗(yàn)證等功能?。
1. HttpClient
HttpClient
是一個(gè)現(xiàn)代的、高效的 HTTP 客戶端,支持異步操作,適用于 .NET Core 和 .NET Framework。
主要方法
? GetAsync:發(fā)送 GET 請(qǐng)求。
? PostAsync:發(fā)送 POST 請(qǐng)求。
? PutAsync:發(fā)送 PUT 請(qǐng)求。
? DeleteAsync:發(fā)送 DELETE 請(qǐng)求。
? SendAsync:發(fā)送任意類型的 HTTP 請(qǐng)求。
注意
? 單例模式:HttpClient 實(shí)例應(yīng)該盡量復(fù)用,而不是每次請(qǐng)求都創(chuàng)建新的實(shí)例。頻繁創(chuàng)建 HttpClient 實(shí)例會(huì)導(dǎo)致資源泄漏和性能問題。
? 異常處理:使用 EnsureSuccessStatusCode
方法來確保請(qǐng)求成功,否則會(huì)拋出 HttpRequestException
。
? 超時(shí)設(shè)置:設(shè)置合理的超時(shí)時(shí)間,避免長(zhǎng)時(shí)間等待。
? 取消請(qǐng)求:使用 CancellationToken 來取消長(zhǎng)時(shí)間運(yùn)行的請(qǐng)求。
示例代碼
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;class HttpClientExample
{private static readonly HttpClient client = new HttpClient();static async Task Main(string[] args){try{// 設(shè)置超時(shí)時(shí)間client.Timeout = TimeSpan.FromSeconds(30);// 發(fā)送 GET 請(qǐng)求HttpResponseMessage response = await client.GetAsync("https://api.example.com/data");response.EnsureSuccessStatusCode(); // 確保請(qǐng)求成功string responseBody = await response.Content.ReadAsStringAsync();Console.WriteLine("GET Response: " + responseBody);// 發(fā)送 POST 請(qǐng)求var content = new StringContent("{\"key\":\"value\"}", System.Text.Encoding.UTF8, "application/json");response = await client.PostAsync("https://api.example.com/post", content);response.EnsureSuccessStatusCode();responseBody = await response.Content.ReadAsStringAsync();Console.WriteLine("POST Response: " + responseBody);}catch (HttpRequestException ex){Console.WriteLine("HTTP Error: " + ex.Message);}catch (TaskCanceledException ex){Console.WriteLine("Request canceled: " + ex.Message);}catch (Exception ex){Console.WriteLine("Error: " + ex.Message);}}
}
2. WebClient
WebClient
是一個(gè)較老的類,提供了簡(jiǎn)單的同步和異步方法來下載和上傳數(shù)據(jù)。雖然它仍然可用,但推薦使用 HttpClient。
主要方法
? DownloadString:下載字符串內(nèi)容。
? UploadString:上傳字符串內(nèi)容。
? DownloadFile:下載文件。
? UploadFile:上傳文件。
注意
? 同步方法:WebClient
的同步方法會(huì)阻塞當(dāng)前線程,建議使用異步方法。
? 異常處理:使用 try-catch
塊來捕獲和處理異常。
? 資源管理:使用 using
語(yǔ)句來確保 WebClient 實(shí)例在使用后被正確釋放。
示例代碼
using System;
using System.Net;class WebClientExample
{static void Main(string[] args){try{using (WebClient client = new WebClient()){// 下載字符串內(nèi)容string response = client.DownloadString("https://api.example.com/data");Console.WriteLine("GET Response: " + response);// 上傳字符串內(nèi)容string uploadData = "{\"key\":\"value\"}";response = client.UploadString("https://api.example.com/post", uploadData);Console.WriteLine("POST Response: " + response);}}catch (WebException ex){Console.WriteLine("Web Error: " + ex.Message);}catch (Exception ex){Console.WriteLine("Error: " + ex.Message);}}
}
3. HttpRequestMessage
HttpRequestMessage 用于構(gòu)建 HTTP 請(qǐng)求,通常與 HttpClient 一起使用,提供更細(xì)粒度的控制。
注意
? 請(qǐng)求頭設(shè)置:根據(jù)需要設(shè)置請(qǐng)求頭,例如 Content-Type
、Authorization
等。
? 請(qǐng)求體設(shè)置:對(duì)于 POST
、PUT
等請(qǐng)求,需要設(shè)置請(qǐng)求體內(nèi)容。
? 響應(yīng)處理:處理響應(yīng)內(nèi)容時(shí),注意檢查響應(yīng)狀態(tài)碼和內(nèi)容類型。
示例代碼
using System;
using System.Net.Http;
using System.Threading.Tasks;class HttpRequestMessageExample
{static async Task Main(string[] args){using (HttpClient client = new HttpClient()){try{// 構(gòu)建 GET 請(qǐng)求HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://api.example.com/data");HttpResponseMessage response = await client.SendAsync(request);response.EnsureSuccessStatusCode();string responseBody = await response.Content.ReadAsStringAsync();Console.WriteLine("GET Response: " + responseBody);// 構(gòu)建 POST 請(qǐng)求request = new HttpRequestMessage(HttpMethod.Post, "https://api.example.com/post"){Content = new StringContent("{\"key\":\"value\"}", System.Text.Encoding.UTF8, "application/json")};response = await client.SendAsync(request);response.EnsureSuccessStatusCode();responseBody = await response.Content.ReadAsStringAsync();Console.WriteLine("POST Response: " + responseBody);}catch (HttpRequestException ex){Console.WriteLine("HTTP Error: " + ex.Message);}catch (Exception ex){Console.WriteLine("Error: " + ex.Message);}}}
}
4. HttpMessageHandler
HttpMessageHandler
是 HttpClient 的基礎(chǔ)組件,用于處理 HTTP 請(qǐng)求和響應(yīng)。通常情況下,開發(fā)者不需要直接使用 HttpMessageHandler,但在某些高級(jí)場(chǎng)景中,可以自定義消息處理器來實(shí)現(xiàn)特定的功能。
注意
? 自定義處理:在 SendAsync
方法中添加自定義邏輯,例如日志記錄、請(qǐng)求攔截等。
? 資源管理:確保自定義的消息處理器在使用后被正確釋放。
示例代碼
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;class CustomMessageHandler : DelegatingHandler
{protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken){try{// 在發(fā)送請(qǐng)求之前添加自定義邏輯Console.WriteLine("Sending request to: " + request.RequestUri);// 調(diào)用基類的 SendAsync 方法HttpResponseMessage response = await base.SendAsync(request, cancellationToken);// 在接收響應(yīng)之后添加自定義邏輯Console.WriteLine("Received response from: " + request.RequestUri);return response;}catch (Exception ex){Console.WriteLine("Error in message handler: " + ex.Message);throw;}}
}class HttpMessageHandlerExample
{static async Task Main(string[] args){try{// 創(chuàng)建自定義消息處理器CustomMessageHandler handler = new CustomMessageHandler();// 使用自定義消息處理器創(chuàng)建 HttpClientusing (HttpClient client = new HttpClient(handler)){// 發(fā)送 GET 請(qǐng)求HttpResponseMessage response = await client.GetAsync("https://api.example.com/data");response.EnsureSuccessStatusCode();string responseBody = await response.Content.ReadAsStringAsync();Console.WriteLine("GET Response: " + responseBody);}}catch (HttpRequestException ex){Console.WriteLine("HTTP Error: " + ex.Message);}catch (Exception ex){Console.WriteLine("Error: " + ex.Message);}}
}
總結(jié)
? HttpClient:現(xiàn)代、高效的 HTTP 客戶端,支持異步操作,推薦使用;單例模式、異常處理、超時(shí)設(shè)置、取消請(qǐng)求。
? WebClient:較老的類,簡(jiǎn)單易用,但推薦使用 HttpClient;同步方法、異常處理、資源管理。
? HttpRequestMessage:用于構(gòu)建 HTTP 請(qǐng)求,通常與 HttpClient 一起使用;請(qǐng)求頭設(shè)置、請(qǐng)求體設(shè)置、響應(yīng)處理。
? HttpMessageHandler:用于處理 HTTP 請(qǐng)求和響應(yīng),通常用于高級(jí)場(chǎng)景;:自定義處理、資源管理。
5.網(wǎng)絡(luò)安全?
C# 網(wǎng)絡(luò)編程中有效地保護(hù)應(yīng)用程序的安全。確保數(shù)據(jù)傳輸?shù)陌踩?、正確處理用戶輸入、實(shí)施適當(dāng)?shù)纳矸蒡?yàn)證和授權(quán)機(jī)制,以及遵循其他最佳實(shí)踐,都是構(gòu)建安全網(wǎng)絡(luò)應(yīng)用程序的關(guān)鍵步驟,包括SSL/TLS加密、密碼安全存儲(chǔ)、防止SQL注入、防止跨站腳本攻擊(XSS)、防止跨站請(qǐng)求偽造(CSRF)、身份驗(yàn)證和授權(quán)等?。
1. SSL/TLS 加密
使用 SSL/TLS
可以確保數(shù)據(jù)在傳輸過程中不被竊聽或篡改。
示例:使用 HttpClient
進(jìn)行 HTTPS 請(qǐng)求
using System;
using System.Net.Http;
using System.Threading.Tasks;class HttpsExample
{static async Task Main(string[] args){using (HttpClient client = new HttpClient()){try{HttpResponseMessage response = await client.GetAsync("https://api.example.com/data");response.EnsureSuccessStatusCode();string responseBody = await response.Content.ReadAsStringAsync();Console.WriteLine(responseBody);}catch (HttpRequestException e){Console.WriteLine("\nException Caught!");Console.WriteLine("Message :{0} ", e.Message);}}}
}
2. 密碼安全存儲(chǔ)
使用哈希算法和鹽值來安全地存儲(chǔ)密碼。
示例:使用 PasswordHasher
進(jìn)行密碼哈希
using Microsoft.AspNetCore.Identity;
using System;class PasswordStorageExample
{static void Main(string[] args){var passwordHasher = new PasswordHasher<string>();string password = "securePassword123";string hashedPassword = passwordHasher.HashPassword(null, password);Console.WriteLine("Hashed Password: " + hashedPassword);PasswordVerificationResult result = passwordHasher.VerifyHashedPassword(null, hashedPassword, password);Console.WriteLine("Verification Result: " + result);}
}
3. 防止 SQL 注入
使用參數(shù)化查詢來防止 SQL
注入。
示例:使用 SqlCommand
進(jìn)行參數(shù)化查詢
using System;
using System.Data.SqlClient;class SqlInjectionExample
{static void Main(string[] args){string connectionString = "your_connection_string_here";string query = "SELECT * FROM Users WHERE Username = @Username AND Password = @Password";using (SqlConnection connection = new SqlConnection(connectionString)){SqlCommand command = new SqlCommand(query, connection);command.Parameters.AddWithValue("@Username", "user1");command.Parameters.AddWithValue("@Password", "pass1");connection.Open();SqlDataReader reader = command.ExecuteReader();while (reader.Read()){Console.WriteLine(reader["Username"]);}}}
}
4. 防止跨站腳本攻擊 (XSS)
對(duì)用戶輸入進(jìn)行適當(dāng)?shù)霓D(zhuǎn)義和驗(yàn)證。
示例:使用 HttpUtility.HtmlEncode
轉(zhuǎn)義 HTML
內(nèi)容
using System;
using System.Web;class XssExample
{static void Main(string[] args){string userInput = "<script>alert('XSS')</script>";string safeOutput = HttpUtility.HtmlEncode(userInput);Console.WriteLine("Safe Output: " + safeOutput);}
}
5. 防止跨站請(qǐng)求偽造 (CSRF)
使用 CSRF 令牌來防止跨站請(qǐng)求偽造。
示例:ASP.NET Core
中的 CSRF
保護(hù)
在 ASP.NET Core 中,CSRF 保護(hù)是默認(rèn)啟用的。確保在表單中包含 CSRF 令牌。
@model YourModel<form method="post">@Html.AntiForgeryToken()<!-- Form fields here --><button type="submit">Submit</button>
</form>
6. 身份驗(yàn)證和授權(quán)
使用身份驗(yàn)證和授權(quán)機(jī)制來保護(hù)應(yīng)用程序。
示例:ASP.NET Core 中的身份驗(yàn)證和授權(quán)
在 Startup.cs
中配置身份驗(yàn)證和授權(quán)。
public class Startup
{public void ConfigureServices(IServiceCollection services){services.AddAuthentication(options =>{options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;}).AddCookie();services.AddAuthorization();services.AddControllersWithViews();}public void Configure(IApplicationBuilder app, IWebHostEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}else{app.UseExceptionHandler("/Home/Error");app.UseHsts();}app.UseHttpsRedirection();app.UseStaticFiles();app.UseRouting();app.UseAuthentication();app.UseAuthorization();app.UseEndpoints(endpoints =>{endpoints.MapControllerRoute(name: "default",pattern: "{controller=Home}/{action=Index}/{id?}");});}
}
7. 其他安全措施
? 輸入驗(yàn)證:對(duì)所有用戶輸入進(jìn)行驗(yàn)證,確保其符合預(yù)期格式。
? 輸出編碼:對(duì)輸出進(jìn)行適當(dāng)?shù)木幋a,防止 XSS
攻擊。
? 最小權(quán)限原則:確保應(yīng)用程序以最小權(quán)限運(yùn)行,限制不必要的權(quán)限。
? 定期更新和補(bǔ)丁:定期更新所有依賴庫(kù)和框架,應(yīng)用最新的安全補(bǔ)丁。
? 日志記錄和監(jiān)控:實(shí)施詳細(xì)的日志記錄和監(jiān)控,以便及時(shí)發(fā)現(xiàn)和響應(yīng)安全事件。
6.多線程與并發(fā)(待續(xù))
? Thread 類:System.Threading.Thread 用于創(chuàng)建和管理線程。
? ThreadPool 類:System.Threading.ThreadPool 用于管理線程池。
? Task 并發(fā):使用 Task.Run 和 Parallel 類進(jìn)行并行任務(wù)處理。
7.序列化與反序列化(待續(xù))
? JSON 序列化:使用 System.Text.Json.JsonSerializer 進(jìn)行 JSON 序列化和反序列化。
? XML 序列化:使用 System.Xml.Serialization.XmlSerializer 進(jìn)行 XML 序列化和反序列化。
8.網(wǎng)絡(luò)配置(待續(xù))
? 配置文件:使用 appsettings.json 或 app.config 配置網(wǎng)絡(luò)參數(shù)。
? 環(huán)境變量:從環(huán)境變量中讀取網(wǎng)絡(luò)配置信息。