C# 网络编程--基础核心内容
在现今软件开发中,网络编程是非常重要的一部分,本文简要介绍下网络编程的概念和实践。
C#网络编程的主要内容包括以下几个方面:
:
上图引用大佬的图,大家也关注一下,有技术有品质,有国有家,情怀满满的杨老师(不得不去仰慕一番哈哈)
https://blog.csdn.net/Eastmount/article/details/9321153
1. 底层网络协议类
如NetworkStream、TcpClient与TcpListener、UdpClient等,这些类提供了更底层的网络操作接口,适用于需要直接控制网络连接和数据处理的情况
1. TCP 通信
使用 TcpListener 和 TcpClient 进行 通讯
- TCP 服务器端示例
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;class TcpServerExample
{static async Task Main(string[] args){// 创建一个 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.");// 处理客户端请求_ = HandleClient(client);}}static async Task HandleClient(TcpClient client){try{NetworkStream stream = client.GetStream();// 接收数据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);// 发送响应string response = "Hello, Client!";byte[] responseData = Encoding.ASCII.GetBytes(response);await stream.WriteAsync(responseData, 0, responseData.Length);Console.WriteLine("Sent: " + response);// 关闭连接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{// 创建一个 TCP/IP 套接字TcpClient client = new TcpClient();await client.ConnectAsync("127.0.0.1", 13000);Console.WriteLine("Connected to server.");NetworkStream stream = client.GetStream();// 发送数据string message = "Hello, Server!";byte[] data = Encoding.ASCII.GetBytes(message);await stream.WriteAsync(data, 0, data.Length);Console.WriteLine("Sent: " + message);// 接收响应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);// 关闭连接client.Close();}catch (Exception e){Console.WriteLine("Error: " + e.Message);}}
}
2. UDP 通信
使用 UdpClient 进行通讯
- UDP 服务器端示例
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;class UdpServerExample
{static async Task Main(string[] args){// 创建一个 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){// 接收数据byte[] buffer = await listener.ReceiveAsync();string request = Encoding.ASCII.GetString(buffer);Console.WriteLine("Received: " + request + " from " + remoteEndPoint.ToString());// 发送响应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{// 创建一个 UDP/IP 套接字UdpClient client = new UdpClient();IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000);// 发送数据string message = "Hello, Server!";byte[] data = Encoding.ASCII.GetBytes(message);await client.SendAsync(data, data.Length, remoteEP);Console.WriteLine("Sent: " + message);// 接收响应UdpReceiveResult result = await client.ReceiveAsync();string response = Encoding.ASCII.GetString(result.Buffer);Console.WriteLine("Received: " + response + " from " + result.RemoteEndPoint.ToString());// 关闭连接client.Close();}catch (Exception e){Console.WriteLine("Error: " + e.Message);}}
}
3. 使用 NetworkStream 进行自定义协议通信
NetworkStream 提供了一个流式接口,可以用于读取和写入网络数据。以下是一个使用 NetworkStream 的示例,展示如何实现一个简单的自定义协议。
- 自定义协议服务器端示例
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;class CustomProtocolServerExample
{static async Task Main(string[] args){// 创建一个 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.");// 处理客户端请求_ = HandleClient(client);}}static async Task HandleClient(TcpClient client){try{NetworkStream stream = client.GetStream();// 接收数据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);// 解析自定义协议string[] parts = request.Split(':');if (parts.Length == 2 && parts[0] == "COMMAND"){string command = parts[1];Console.WriteLine("Command: " + command);// 处理命令并生成响应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);}// 关闭连接client.Close();}catch (Exception ex){Console.WriteLine("Error: " + ex.Message);}}
}
- 自定义协议客户端示例
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;class CustomProtocolClientExample
{static async Task Main(string[] args){try{// 创建一个 TCP/IP 套接字TcpClient client = new TcpClient();await client.ConnectAsync("127.0.0.1", 13000);Console.WriteLine("Connected to server.");NetworkStream stream = client.GetStream();// 发送自定义协议命令string message = "COMMAND:Hello";byte[] data = Encoding.ASCII.GetBytes(message);await stream.WriteAsync(data, 0, data.Length);Console.WriteLine("Sent: " + message);// 接收响应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);// 关闭连接client.Close();}catch (Exception e){Console.WriteLine("Error: " + e.Message);}}
}
2.Socket编程
也就是我们常说的“套接字”,Socket类在System.Net.Sockets命名空间下,是最基本的网络操作类,封装了网络连接的创建和关闭、数据的收发以及网络状态监控等功能。通过Socket类,可以实现基于TCP和UDP的网络通信。
1. 使用 Socket 类进行 TCP 通信
TCP 服务器端示例
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;class TcpServerExample
{static async Task Main(string[] args){// 创建一个 TCP/IP 套接字Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// 绑定套接字到本地端口IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 13000);listener.Bind(localEndPoint);// 监听传入连接listener.Listen(10);Console.WriteLine("Server started. Waiting for connections...");while (true){// 接受传入连接Socket handler = await listener.AcceptAsync();Console.WriteLine("Client connected.");// 处理客户端请求_ = HandleClient(handler);}}static async Task HandleClient(Socket handler){try{// 接收数据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);// 发送响应string response = "Hello, Client!";byte[] responseData = Encoding.ASCII.GetBytes(response);await handler.SendAsync(new ArraySegment<byte>(responseData), SocketFlags.None);Console.WriteLine("Sent: " + response);// 关闭连接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{// 创建一个 TCP/IP 套接字Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// 连接到服务器IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 13000);await client.ConnectAsync(remoteEP);Console.WriteLine("Connected to server.");// 发送数据string message = "Hello, Server!";byte[] data = Encoding.ASCII.GetBytes(message);await client.SendAsync(new ArraySegment<byte>(data), SocketFlags.None);Console.WriteLine("Sent: " + message);// 接收响应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);// 关闭连接client.Shutdown(SocketShutdown.Both);client.Close();}catch (Exception e){Console.WriteLine("Error: " + e.Message);}}
}
2. 使用 Socket 类进行 UDP 通信
UDP 服务器端示例
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;class UdpServerExample
{static async Task Main(string[] args){// 创建一个 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){// 接收数据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());// 发送响应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{// 创建一个 UDP/IP 套接字Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);// 连接到服务器IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000);// 发送数据string message = "Hello, Server!";byte[] data = Encoding.ASCII.GetBytes(message);await client.SendToAsync(new ArraySegment<byte>(data), SocketFlags.None, remoteEP);Console.WriteLine("Sent: " + message);// 接收响应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());// 关闭连接client.Close();}catch (Exception e){Console.WriteLine("Error: " + e.Message);}}
}
注意事项
- 异常处理:使用 try-catch 块来捕获和处理异常。
- 资源管理:确保在使用完 Socket 后调用 Close 方法来释放资源。
- 并发处理:对于服务器端,通常需要处理多个客户端连接,可以使用多线程或异步编程来提高并发性能。
- 超时设置:对于 TCP 连接,可以设置超时时间来避免长时间等待。
3.WebSocket通信
WebSocket是一种在单个TCP连接上进行全双工通讯的协议。可以使用 System.Net.WebSockets 命名空间中的类来创建 WebSocket 服务器和客户端。WebSocket通信常用于需要实时数据交换的应用场景,适用于需要实时数据交换的应用场景,如实时聊天、在线游戏、股票行情等。
1.WebSocket 服务器端示例
以下是一个简单的 WebSocket 服务器端示例,使用 HttpListener 来处理 HTTP 请求并升级为 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 客户端示例
以下是一个简单的 WebSocket 客户端示例,使用 ClientWebSocket 类来连接 WebSocket 服务器并进行通信。
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];// 在单独的任务中开始接收消息_ = ReceiveMessages(webSocket, buffer);// 向服务器发送消息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);}}
}
注意事项
- 异常处理:使用 try-catch 块来捕获和处理异常,特别是网络相关的异常。
- 资源管理:确保在使用完 WebSocket 后调用 CloseAsync 和 Dispose 方法来释放资源。
- 并发处理:对于服务器端,通常需要处理多个客户端连接,可以使用多线程或异步编程来提高并发性能。
- 安全性:在生产环境中,建议使用
wss://(WebSocket Secure)来加密通信,防止数据泄露。 - 心跳机制:为了保持连接活跃,可以定期发送心跳消息,防止中间设备关闭空闲连接。
4. HTTP请求:
可以使用HttpClient、WebClient、HttpRequestMessage和HttpMessageHandler等类来发送HTTP请求。这些类提供了发送GET、POST等请求的方法,并支持异步操作和身份验证等功能。
1. HttpClient
HttpClient 是一个现代的、高效的 HTTP 客户端,支持异步操作,适用于 .NET Core 和 .NET Framework。
主要方法
• GetAsync:发送 GET 请求。
• PostAsync:发送 POST 请求。
• PutAsync:发送 PUT 请求。
• DeleteAsync:发送 DELETE 请求。
• SendAsync:发送任意类型的 HTTP 请求。
注意
• 单例模式:HttpClient 实例应该尽量复用,而不是每次请求都创建新的实例。频繁创建 HttpClient 实例会导致资源泄漏和性能问题。
• 异常处理:使用 EnsureSuccessStatusCode 方法来确保请求成功,否则会抛出 HttpRequestException。
• 超时设置:设置合理的超时时间,避免长时间等待。
• 取消请求:使用 CancellationToken 来取消长时间运行的请求。
示例代码
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{// 设置超时时间client.Timeout = TimeSpan.FromSeconds(30);// 发送 GET 请求HttpResponseMessage response = await client.GetAsync("https://api.example.com/data");response.EnsureSuccessStatusCode(); // 确保请求成功string responseBody = await response.Content.ReadAsStringAsync();Console.WriteLine("GET Response: " + responseBody);// 发送 POST 请求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 是一个较老的类,提供了简单的同步和异步方法来下载和上传数据。虽然它仍然可用,但推荐使用 HttpClient。
主要方法
• DownloadString:下载字符串内容。
• UploadString:上传字符串内容。
• DownloadFile:下载文件。
• UploadFile:上传文件。
注意
• 同步方法:WebClient 的同步方法会阻塞当前线程,建议使用异步方法。
• 异常处理:使用 try-catch 块来捕获和处理异常。
• 资源管理:使用 using 语句来确保 WebClient 实例在使用后被正确释放。
示例代码
using System;
using System.Net;class WebClientExample
{static void Main(string[] args){try{using (WebClient client = new WebClient()){// 下载字符串内容string response = client.DownloadString("https://api.example.com/data");Console.WriteLine("GET Response: " + response);// 上传字符串内容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 用于构建 HTTP 请求,通常与 HttpClient 一起使用,提供更细粒度的控制。
注意
• 请求头设置:根据需要设置请求头,例如 Content-Type、Authorization 等。
• 请求体设置:对于 POST、PUT 等请求,需要设置请求体内容。
• 响应处理:处理响应内容时,注意检查响应状态码和内容类型。
示例代码
using System;
using System.Net.Http;
using System.Threading.Tasks;class HttpRequestMessageExample
{static async Task Main(string[] args){using (HttpClient client = new HttpClient()){try{// 构建 GET 请求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);// 构建 POST 请求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 的基础组件,用于处理 HTTP 请求和响应。通常情况下,开发者不需要直接使用 HttpMessageHandler,但在某些高级场景中,可以自定义消息处理器来实现特定的功能。
注意
• 自定义处理:在 SendAsync 方法中添加自定义逻辑,例如日志记录、请求拦截等。
• 资源管理:确保自定义的消息处理器在使用后被正确释放。
示例代码
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{// 在发送请求之前添加自定义逻辑Console.WriteLine("Sending request to: " + request.RequestUri);// 调用基类的 SendAsync 方法HttpResponseMessage response = await base.SendAsync(request, cancellationToken);// 在接收响应之后添加自定义逻辑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{// 创建自定义消息处理器CustomMessageHandler handler = new CustomMessageHandler();// 使用自定义消息处理器创建 HttpClientusing (HttpClient client = new HttpClient(handler)){// 发送 GET 请求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);}}
}
总结
• HttpClient:现代、高效的 HTTP 客户端,支持异步操作,推荐使用;单例模式、异常处理、超时设置、取消请求。
• WebClient:较老的类,简单易用,但推荐使用 HttpClient;同步方法、异常处理、资源管理。
• HttpRequestMessage:用于构建 HTTP 请求,通常与 HttpClient 一起使用;请求头设置、请求体设置、响应处理。
• HttpMessageHandler:用于处理 HTTP 请求和响应,通常用于高级场景;:自定义处理、资源管理。
5.网络安全
C# 网络编程中有效地保护应用程序的安全。确保数据传输的安全性、正确处理用户输入、实施适当的身份验证和授权机制,以及遵循其他最佳实践,都是构建安全网络应用程序的关键步骤,包括SSL/TLS加密、密码安全存储、防止SQL注入、防止跨站脚本攻击(XSS)、防止跨站请求伪造(CSRF)、身份验证和授权等。
1. SSL/TLS 加密
使用 SSL/TLS 可以确保数据在传输过程中不被窃听或篡改。
示例:使用 HttpClient 进行 HTTPS 请求
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. 密码安全存储
使用哈希算法和盐值来安全地存储密码。
示例:使用 PasswordHasher 进行密码哈希
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 注入
使用参数化查询来防止 SQL 注入。
示例:使用 SqlCommand 进行参数化查询
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)
对用户输入进行适当的转义和验证。
示例:使用 HttpUtility.HtmlEncode 转义 HTML 内容
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. 防止跨站请求伪造 (CSRF)
使用 CSRF 令牌来防止跨站请求伪造。
示例:ASP.NET Core 中的 CSRF 保护
在 ASP.NET Core 中,CSRF 保护是默认启用的。确保在表单中包含 CSRF 令牌。
@model YourModel<form method="post">@Html.AntiForgeryToken()<!-- Form fields here --><button type="submit">Submit</button>
</form>
6. 身份验证和授权
使用身份验证和授权机制来保护应用程序。
示例:ASP.NET Core 中的身份验证和授权
在 Startup.cs 中配置身份验证和授权。
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. 其他安全措施
• 输入验证:对所有用户输入进行验证,确保其符合预期格式。
• 输出编码:对输出进行适当的编码,防止 XSS 攻击。
• 最小权限原则:确保应用程序以最小权限运行,限制不必要的权限。
• 定期更新和补丁:定期更新所有依赖库和框架,应用最新的安全补丁。
• 日志记录和监控:实施详细的日志记录和监控,以便及时发现和响应安全事件。
6.多线程与并发(待续)
• Thread 类:System.Threading.Thread 用于创建和管理线程。
• ThreadPool 类:System.Threading.ThreadPool 用于管理线程池。
• Task 并发:使用 Task.Run 和 Parallel 类进行并行任务处理。
7.序列化与反序列化(待续)
• JSON 序列化:使用 System.Text.Json.JsonSerializer 进行 JSON 序列化和反序列化。
• XML 序列化:使用 System.Xml.Serialization.XmlSerializer 进行 XML 序列化和反序列化。
8.网络配置(待续)
• 配置文件:使用 appsettings.json 或 app.config 配置网络参数。
• 环境变量:从环境变量中读取网络配置信息。
相关文章:
C# 网络编程--基础核心内容
在现今软件开发中,网络编程是非常重要的一部分,本文简要介绍下网络编程的概念和实践。 C#网络编程的主要内容包括以下几个方面: : 上图引用大佬的图,大家也关注一下,有技术有品质,有国有家,情…...
【C++游戏程序】easyX图形库还原游戏《贪吃蛇大作战》(三)
承接上一篇文章:【C游戏程序】easyX图形库还原游戏《贪吃蛇大作战》(二),我们这次来补充一些游戏细节,以及增加吃食物加长角色长度等设定玩法,也是本游戏的最后一篇文章。 一.玩家边界检测 首先是用来检测…...
uni-app H5端使用注意事项 【跨端开发系列】
🔗 uniapp 跨端开发系列文章:🎀🎀🎀 uni-app 组成和跨端原理 【跨端开发系列】 uni-app 各端差异注意事项 【跨端开发系列】uni-app 离线本地存储方案 【跨端开发系列】uni-app UI库、框架、组件选型指南 【跨端开…...
SpringBoot中的@Configuration注解
在Spring Boot中,Configuration注解扮演着非常重要的角色,它是Spring框架中用于定义配置类的一个核心注解。以下是Configuration注解的主要作用: 定义配置类: 使用Configuration注解的类表示这是一个配置类,Spring容器…...
十二、路由、生命周期函数
router路由 页面路由指的是在应用程序中实现不同页面之间的跳转,以及数据传递。通过 Router 模块就可以实现这个功能 2.1创建页面 之前是创建的文件,使用路由的时候需要创建页面,步骤略有不同 方法 1:直接右键新建Page(常用)方法 2:单独添加页面并配置2.1.1直接右键新建…...
【蓝桥杯每日一题】X 进制减法
X 进制减法 2024-12-6 蓝桥杯每日一题 X 进制减法 贪心 进制转换 题目大意 进制规定了数字在数位上逢几进一。 XX 进制是一种很神奇的进制, 因为其每一数位的进制并不固定!例如说某 种 XX 进制数, 最低数位为二进制, 第二数位为十进制, 第三数位为八进制, 则 XX 进制…...
《蓝桥杯比赛规划》
大家好啊!我是NiJiMingCheng 我的博客:NiJiMingCheng 这节课我们来分享蓝桥杯比赛规划,好的规划会给我们的学习带来良好的收益,废话少说接下来就让我们进入学习规划吧,加油哦!!! 一、…...
C++算法练习day70——53.最大子序和
题目来源:. - 力扣(LeetCode) 题目思路分析 题目:寻找最大子数组和(也称为最大子序和)。 给定一个整数数组 nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素&#x…...
import是如何“占领满屏“
import是如何“占领满屏“的? 《拒绝使用模块重导(Re-export)》 模块重导是一种通用的技术。在腾讯、字节、阿里等各大厂的组件库中都有大量使用。 如:字节的arco-design组件库中的组件:github.com/arco-design… …...
ceph /etc/ceph-csi-config/config.json: no such file or directory
环境 rook-ceph 部署的 ceph。 问题 kubectl describe pod dragonfly-redis-master-0Warning FailedMount 7m59s (x20 over 46m) kubelet MountVolume.MountDevice failed for volume "pvc-c63e159a-c940-4001-bf0d-e6141634cc55" : rpc error: cod…...
C语言——验证“哥德巴赫猜想”
问题描述: 验证"哥德巴赫猜想" 任何一个大于2的偶数都可以表示为两个质数之和。例如,4可以表示为22,6可以表示为33,8可以表示为35等 //验证"哥德巴赫猜想" //任何一个大于2的偶数都可以表示为两个质数之和…...
Flourish笔记:柱状图(Column chart (grouped))
文章目录 样式设定Chart Type:图表类型Controls & Filters:展示方式Colors:颜色bars:柱子的调整labels:柱子数字标注X axis:横坐标标签Y axis:纵坐标标签Plot BackgroundNumber FormatingLe…...
深度学习案例:DenseNet + SE-Net
本文为为🔗365天深度学习训练营内部文章 原作者:K同学啊 一 回顾DenseNet算法 DenseNet(Densely Connected Convolutional Networks)是一种深度卷积神经网络架构,提出的核心思想是通过在每一层与前面所有层进行直接连接…...
excel文件合并,每个excel名称插入excel列
import pandas as pd import os # 设置文件夹路径 folder_path rC:\test # 替换为您的下载文件夹路径 output_file os.path.join(folder_path, BOM材料.xlsx) # 创建一个空的 DataFrame 用于存储合并的数据 combined_data pd.DataFrame() # 遍历文件夹中的所有文件 for …...
Linux 如何设置特殊权限?
简介 通过使用 setuid、setgid 、sticky,它们是 Linux 中的特殊权限,可以对文件和目录的访问和执行方式提供额外的控制。 命令八进制数字功能setuid4当执行文件时,它以文件所有者的权限运行,而不是执行它的用户的权限运行。setg…...
零基础如何使用ChatGPT快速学习Python
引言 AI编程时代来临,没有编程基础可以快速上车享受时代的红利吗?答案是肯定的。本文旨在介绍零基础如何利用ChatGPT快速学习Python编程语言,开启AI编程之路。解决的问题包括:传统学习方式效率低、缺乏互动性以及学习资源质量参差…...
【开源】一款基于SpringBoot 的全开源充电桩平台
一、下载项目文件 下载源码项目文件口令:动作璆璜量子屏多好/~d1b8356ox2~:/复制口令后,进入夸克网盘app即可保存(如果复制到夸克app没有跳转资源,可以复制粘贴口令到夸克app的搜索框也可以打开(不用点搜索按钮&#…...
AI - RAG中的状态化管理聊天记录
AI - RAG中的状态化管理聊天记录 大家好,今天我们来聊聊LangChain和LLM中一个重要的话题——状态化管理聊天记录。在使用大语言模型(LLM)的时候,聊天记录(History)和状态(State)管理是非常关键的。那我们先…...
JAVA安全—SpringBoot框架MyBatis注入Thymeleaf模板注入
前言 之前我们讲了JAVA的一些组件安全,比如Log4j,fastjson。今天讲一下框架安全,就是这个也是比较常见的SpringBoot框架。 SpringBoot框架 Spring Boot是由Pivotal团队提供的一套开源框架,可以简化spring应用的创建及部署。它提…...
【STM32系列】提升ADC采样精度的方法
资料地址 兆易创新GigaDevice-资料下载兆易创新GD32 MCU ADC简介 ADC转换包括采样、保持、量化、编码四个步骤。的采样电容上,即在采样开关 SW 关闭的过程中,外部输入信号通过外部的输入电阻 RAIN 和以及 ADC 采样电阻 RADC 对采样电容 CADC 充电。采样…...
树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
32单片机——基本定时器
STM32F103有众多的定时器,其中包括2个基本定时器(TIM6和TIM7)、4个通用定时器(TIM2~TIM5)、2个高级控制定时器(TIM1和TIM8),这些定时器彼此完全独立,不共享任何资源 1、定…...
车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...
Linux操作系统共享Windows操作系统的文件
目录 一、共享文件 二、挂载 一、共享文件 点击虚拟机选项-设置 点击选项,设置文件夹共享为总是启用,点击添加,可添加需要共享的文件夹 查询是否共享成功 ls /mnt/hgfs 如果显示Download(这是我共享的文件夹)&…...
虚幻基础:角色旋转
能帮到你的话,就给个赞吧 😘 文章目录 移动组件使用控制器所需旋转:组件 使用 控制器旋转将旋转朝向运动:组件 使用 移动方向旋转 控制器旋转和移动旋转 缺点移动旋转:必须移动才能旋转,不移动不旋转控制器…...
