运用自定义协议设计与实现“跨网络计算器”
本帖最后由 Shaw0xyz 于 2024-6-20 13:46 编辑1. 引言
在网络编程中,自定义协议可以用来实现特定的功能和需求。本文将介绍如何运用自定义协议设计和实现一个“跨网络计算器”,使得客户端可以通过网络向服务器发送计算请求,并接收结果。我们将从协议设计、服务器实现、客户端实现三个方面详细讲解,最终实现一个可以在局域网内进行简单加减乘除运算的计算器。
2. 协议设计
2.1 协议概述
我们设计的协议将包括请求和响应两个部分。客户端发送计算请求,服务器处理请求并返回结果。
2.2 请求格式
请求格式由操作符和操作数组成。每个请求包含一个操作符(+、-、*、/)和两个操作数,中间以空格分隔。例如:
+ 4 2
2.3 响应格式
响应格式为计算结果的字符串表示。例如,对于上述请求,响应可以是:
6
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;
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;
if (!double.TryParse(parts, out double operand1) || !double.TryParse(parts, 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;
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;
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;
if (!double.TryParse(parts, out double operand1) || !double.TryParse(parts, 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;
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
页:
[1]