|
本帖最后由 Shaw0xyz 于 2024-6-20 13:46 编辑
1. 引言
在网络编程中,自定义协议可以用来实现特定的功能和需求。本文将介绍如何运用自定义协议设计和实现一个“跨网络计算器”,使得客户端可以通过网络向服务器发送计算请求,并接收结果。我们将从协议设计、服务器实现、客户端实现三个方面详细讲解,最终实现一个可以在局域网内进行简单加减乘除运算的计算器。
2. 协议设计
2.1 协议概述
我们设计的协议将包括请求和响应两个部分。客户端发送计算请求,服务器处理请求并返回结果。
2.2 请求格式
请求格式由操作符和操作数组成。每个请求包含一个操作符(+、-、*、/)和两个操作数,中间以空格分隔。例如:
2.3 响应格式
响应格式为计算结果的字符串表示。例如,对于上述请求,响应可以是:
3. 服务器实现
服务器需要能够接收客户端的连接请求,解析计算请求,执行相应的计算,并返回结果。
3.1 创建TCP服务器
首先,我们创建一个TCP服务器来监听客户端的连接请求。
示例:
- int port = 5000;
- TcpListener listener = new TcpListener(IPAddress.Any, port);
- listener.Start();
- Console.WriteLine("Server started on port " + port);
复制代码
3.2 接受并处理客户端连接
服务器接受客户端连接后,读取请求,解析并执行计算,然后返回结果。
示例:
- while (true) {
- TcpClient client = listener.AcceptTcpClient();
- Thread clientThread = new Thread(() => HandleClient(client));
- clientThread.Start();
- }
- void HandleClient(TcpClient client) {
- NetworkStream stream = client.GetStream();
- byte[] buffer = new byte[1024];
- int bytesRead;
- try {
- bytesRead = stream.Read(buffer, 0, buffer.Length);
- string request = Encoding.ASCII.GetString(buffer, 0, bytesRead);
- string response = ProcessRequest(request);
- byte[] responseBytes = Encoding.ASCII.GetBytes(response);
- stream.Write(responseBytes, 0, responseBytes.Length);
- } catch (Exception e) {
- Console.WriteLine("Error: " + e.Message);
- } finally {
- client.Close();
- }
- }
复制代码
3.3 处理请求
服务器需要解析请求并执行相应的计算。
示例:
- string ProcessRequest(string request) {
- string[] parts = request.Split(' ');
- if (parts.Length != 3) {
- return "Error: Invalid request format";
- }
- string operation = parts[0];
- if (!double.TryParse(parts[1], out double operand1) || !double.TryParse(parts[2], out double operand2)) {
- return "Error: Invalid operands";
- }
- double result;
- switch (operation) {
- case "+":
- result = operand1 + operand2;
- break;
- case "-":
- result = operand1 - operand2;
- break;
- case "*":
- result = operand1 * operand2;
- break;
- case "/":
- if (operand2 == 0) return "Error: Division by zero";
- result = operand1 / operand2;
- break;
- default:
- return "Error: Invalid operation";
- }
- return result.ToString();
- }
复制代码
4. 客户端实现
客户端需要能够连接到服务器,发送计算请求,并接收和显示结果。
4.1 创建TCP客户端
客户端连接到服务器并发送计算请求。
示例:
- string server = "127.0.0.1";
- int port = 5000;
- TcpClient client = new TcpClient(server, port);
复制代码
4.2 发送请求
客户端发送计算请求并接收响应。
示例:
- NetworkStream stream = client.GetStream();
- byte[] requestBytes = Encoding.ASCII.GetBytes("+ 4 2");
- stream.Write(requestBytes, 0, requestBytes.Length);
- byte[] responseBytes = new byte[1024];
- int bytesRead = stream.Read(responseBytes, 0, responseBytes.Length);
- string response = Encoding.ASCII.GetString(responseBytes, 0, bytesRead);
- Console.WriteLine("Response: " + response);
- client.Close();
复制代码
5. 完整示例
以下是服务器和客户端的完整示例代码。
5.1 服务器代码
- using System;
- using System.net;
- using System.Net.Sockets;
- using System.Text;
- using System.Threading;
- class Server {
- static void Main() {
- int port = 5000;
- TcpListener listener = new TcpListener(IPAddress.Any, port);
- listener.Start();
- Console.WriteLine("Server started on port " + port);
- while (true) {
- TcpClient client = listener.AcceptTcpClient();
- Thread clientThread = new Thread(() => HandleClient(client));
- clientThread.Start();
- }
- }
- static void HandleClient(TcpClient client) {
- NetworkStream stream = client.GetStream();
- byte[] buffer = new byte[1024];
- int bytesRead;
- try {
- bytesRead = stream.Read(buffer, 0, buffer.Length);
- string request = Encoding.ASCII.GetString(buffer, 0, bytesRead);
- string response = ProcessRequest(request);
- byte[] responseBytes = Encoding.ASCII.GetBytes(response);
- stream.Write(responseBytes, 0, responseBytes.Length);
- } catch (Exception e) {
- Console.WriteLine("Error: " + e.Message);
- } finally {
- client.Close();
- }
- }
- static string ProcessRequest(string request) {
- string[] parts = request.Split(' ');
- if (parts.Length != 3) {
- return "Error: Invalid request format";
- }
- string operation = parts[0];
- if (!double.TryParse(parts[1], out double operand1) || !double.TryParse(parts[2], out double operand2)) {
- return "Error: Invalid operands";
- }
- double result;
- switch (operation) {
- case "+":
- result = operand1 + operand2;
- break;
- case "-":
- result = operand1 - operand2;
- break;
- case "*":
- result = operand1 * operand2;
- break;
- case "/":
- if (operand2 == 0) return "Error: Division by zero";
- result = operand1 / operand2;
- break;
- default:
- return "Error: Invalid operation";
- }
- return result.ToString();
- }
- }
复制代码
5.2 客户端代码
- using System;
- using System.Net.Sockets;
- using System.Text;
- class Client {
- static void Main() {
- string server = "127.0.0.1";
- int port = 5000;
- TcpClient client = new TcpClient(server, port);
- NetworkStream stream = client.GetStream();
- byte[] requestBytes = Encoding.ASCII.GetBytes("+ 4 2");
- stream.Write(requestBytes, 0, requestBytes.Length);
- byte[] responseBytes = new byte[1024];
- int bytesRead = stream.Read(responseBytes, 0, responseBytes.Length);
- string response = Encoding.ASCII.GetString(responseBytes, 0, bytesRead);
- Console.WriteLine("Response: " + response);
- client.Close();
- }
- }
复制代码
6. 结论
本文介绍了如何设计和实现一个“跨网络计算器”。通过定义简单的请求和响应协议,使用C#实现了能够处理并发连接的TCP服务器,并展示了如何实现客户端与服务器之间的通信。希望本文能帮助开发者理解和掌握自定义协议的设计与实现,为实现更复杂的网络应用奠定基础。
/ 荔枝学姐de课后专栏 /
Hi!这里是荔枝学姐~
欢迎来到我的课后专栏
自然语言学渣 NLP摆烂姐
热衷于技术写作 IT边角料
AIGC & Coding & linux ...
~互撩~ TG: @Shaw_0xyz
|
|