我決定使用多執行緒實作一個簡單的客戶端-服務器-客戶端實作。我遇到的問題是從客戶端 A 發送到客戶端 B 的每一秒訊息都會回傳到客戶端 A。我不完全確定為什么會發生這種情況。我有根據的猜測是多執行緒和作為參考傳遞的發送方 IPEndPoint 的組合,但是我真的沒有看到任何解決參考的方法。以下是代碼片段:
服務器代碼:
using System;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace UDP
{
public sealed class UdpServer
{
public static void Main()
{
var ipEndPoint = new IPEndPoint(IPAddress.Loopback, 12345);
var udpServer = new UdpClient(ipEndPoint);
var clientOne = new IPEndPoint(IPAddress.Loopback, 12346);
var clientTwo = new IPEndPoint(IPAddress.Loopback, 12347);
var taskFactory = new TaskFactory();
var tokenSource = new CancellationTokenSource();
var cancellationToken = tokenSource.Token;
var taskArray = new Task[2];
taskArray[0] = taskFactory.StartNew(() => MessagingTask(udpServer, clientOne, clientTwo, tokenSource, cancellationToken), cancellationToken);
taskArray[1] = taskFactory.StartNew(() => MessagingTask(udpServer, clientTwo, clientOne, tokenSource, cancellationToken), cancellationToken);
Task.WaitAny(taskArray);
}
private static void MessagingTask(UdpClient udpServer, IPEndPoint sender, IPEndPoint receiver, CancellationTokenSource tokenSource, CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
var bytes = udpServer.Receive(ref sender);
var message = Encoding.ASCII.GetString(bytes, 0, bytes.Length);
Console.WriteLine($"IP: {sender.Address} Port: {sender.Port}, {DateTime.Now}: {message}");
udpServer.Send(bytes, bytes.Length, receiver);
Console.WriteLine($"Send to: {receiver.Address} Port: {receiver.Port}, {DateTime.Now}: {message}");
}
}
}
}
客戶端代碼:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace UDP
{
public sealed class UdpClientOne
{
public static void Main()
{
var clientEndpoint = new IPEndPoint(IPAddress.Loopback, 12346);
var serverEndpoint = new IPEndPoint(IPAddress.Loopback, 12345);
var udpClient = new UdpClient(clientEndpoint);
var taskFactory = new TaskFactory();
var tokenSource = new CancellationTokenSource();
var cancellationToken = tokenSource.Token;
var taskArray = new Task[2];
taskArray[0] = taskFactory.StartNew(() => ReadingThread(udpClient, serverEndpoint, cancellationToken), cancellationToken);
taskArray[1] = taskFactory.StartNew(() => SendingThread(udpClient, serverEndpoint, tokenSource, cancellationToken), cancellationToken);
Task.WaitAny(taskArray);
udpClient.Close();
}
private static void ReadingThread(UdpClient udpClient, IPEndPoint ipEndPoint, CancellationToken cancellationToken)
{
while (true)
{
if (cancellationToken.IsCancellationRequested)
{
Console.WriteLine("Closing application...");
return;
}
var data = udpClient.Receive(ref ipEndPoint);
var message= Encoding.ASCII.GetString(data, 0, data.Length);
Console.WriteLine($"{DateTime.Now}: {message}");
}
}
private static void SendingThread(UdpClient udpClient, IPEndPoint ipEndPoint, CancellationTokenSource tokenSource, CancellationToken cancellationToken)
{
string userInput = "";
while (true)
{
userInput = Console.ReadLine();
if (string.IsNullOrEmpty(userInput))
continue;
if (userInput.Equals("q"))
{
Console.WriteLine("Closing application...");
tokenSource.Cancel();
}
var bytes = Encoding.ASCII.GetBytes(userInput);
udpClient.Send(bytes, bytes.Length, ipEndPoint);
}
}
}
}
控制臺輸出:

uj5u.com熱心網友回復:
的UdpServer服務器(埠號:12345)正在接收來自客戶端A(埠號:12346)的訊息,然后轉發給客戶端B(埠號:12347)。但是,UdpClientOne的服務器向客戶端 A發送資料并從客戶端 A接收資料。

圖中藍色代表UdpServer班級,紅色代表UdpClientOne班級。兩個箭頭指向服務器(12345埠),因此它將收到兩次訊息。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/481884.html
上一篇:Vue.js-加載資源失敗:服務器回應狀態為401(未授權)
下一篇:我應該如何回復頻道訊息?
