using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
class P2PCoordinator
{
private const int ServerPort = 11000;
private TcpListener _tcpListener;
private readonly Dictionary<string, IPEndPoint> _tcpEndpoints = new();
private readonly Dictionary<string, TcpClient> _tcpConnections = new();
private readonly object _lock = new object();
private bool _isRunning = true;
public P2PCoordinator()
{
try
{
_tcpListener = new TcpListener(IPAddress.Any, ServerPort);
Console.WriteLine($"P2P协调服务器启动,监听端口: {ServerPort}");
}
catch (Exception ex)
{
Console.WriteLine($"服务器初始化失败: {ex.Message}");
Environment.Exit(1);
}
}
public void Start()
{
new Thread(ListenTcp).Start();
Console.WriteLine("服务器运行中. 按任意键停止...");
Console.ReadKey();
Stop();
}
private void ListenTcp()
{
try
{
_tcpListener.Start();
Console.WriteLine("TCP监听已启动");
while (_isRunning)
{
TcpClient client = _tcpListener.AcceptTcpClient();
new Thread(() => HandleTcpClient(client)).Start();
}
}
catch (Exception ex)
{
if (_isRunning) Console.WriteLine($"TCP监听错误: {ex.Message}");
}
}
private void HandleTcpClient(TcpClient client)
{
string clientId = null;
try
{
NetworkStream stream = client.GetStream();
byte[] buffer = new byte[1024];
int bytesRead = stream.Read(buffer, 0, buffer.Length);
if (bytesRead == 0) return;
string message = Encoding.ASCII.GetString(buffer, 0, bytesRead);
string[] parts = message.Split(':');
if (parts.Length < 2) return;
string command = parts[0];
clientId = parts[1];
var clientEP = (IPEndPoint)client.Client.RemoteEndPoint;
Console.WriteLine($"[TCP] {clientId} 连接: {clientEP}");
lock (_lock)
{
if (command == "REGISTER")
{
_tcpEndpoints[clientId] = clientEP;
_tcpConnections[clientId] = client;
Console.WriteLine($"[注册] {clientId} -> {clientEP}");
SendTcpResponse(client, "REGISTERED");
}
else if (command == "CONNECT" && parts.Length > 2)
{
string targetId = parts[2];
Console.WriteLine($"[连接请求] {clientId} -> {targetId}");
HandleConnectionRequest(clientId, targetId);
}
}
// 处理后续消息
while (_isRunning)
{
bytesRead = stream.Read(buffer, 0, buffer.Length);
if (bytesRead == 0) break;
message = Encoding.ASCII.GetString(buffer, 0, bytesRead);
parts = message.Split(':');
command = parts[0];
if (command == "HEARTBEAT")
{
// 心跳检测
SendTcpResponse(client, "HEARTBEAT_ACK");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"处理TCP客户端错误: {ex.Message}");
}
finally
{
if (clientId != null)
{
lock (_lock)
{
_tcpConnections.Remove(clientId);
_tcpEndpoints.Remove(clientId);
}
}
client.Close();
}
}
private void HandleConnectionRequest(string fromClient, string toClient)
{
lock (_lock)
{
if (!_tcpConnections.ContainsKey(fromClient))
{
Console.WriteLine($"[错误] 源客户端未连接: {fromClient}");
return;
}
if (!_tcpConnections.ContainsKey(toClient))
{
SendTcpResponse(_tcpConnections[fromClient], "ERROR:目标客户端未连接");
Console.WriteLine($"[错误] 目标客户端未连接: {toClient}");
return;
}
if (!_tcpEndpoints.TryGetValue(fromClient, out IPEndPoint fromEp) ||
!_tcpEndpoints.TryGetValue(toClient, out IPEndPoint toEp))
{
SendTcpResponse(_tcpConnections[fromClient], "ERROR:端点信息不完整");
Console.WriteLine($"[错误] 端点信息不完整: {fromClient} -> {toClient}");
return;
}
// 交换端点信息
string fromMessage = $"PEER_INFO:{toClient}:{toEp.Address}:{toEp.Port}";
string toMessage = $"PEER_INFO:{fromClient}:{fromEp.Address}:{fromEp.Port}";
SendTcpResponse(_tcpConnections[fromClient], fromMessage);
SendTcpResponse(_tcpConnections[toClient], toMessage);
Console.WriteLine($"[端点交换] {fromClient} <-> {toClient}");
Console.WriteLine($" {fromEp} <-> {toEp}");
}
}
private void SendTcpResponse(TcpClient client, string message)
{
try
{
if (client.Connected)
{
NetworkStream stream = client.GetStream();
byte[] data = Encoding.ASCII.GetBytes(message);
stream.Write(data, 0, data.Length);
}
}
catch (Exception ex)
{
Console.WriteLine($"发送TCP响应错误: {ex.Message}");
}
}
private void Stop()
{
Console.WriteLine("停止服务器...");
_isRunning = false;
try
{
lock (_lock)
{
foreach (var client in _tcpConnections.Values)
{
try { client.Close(); } catch { }
}
_tcpConnections.Clear();
_tcpEndpoints.Clear();
}
_tcpListener.Stop();
Console.WriteLine("服务器已停止");
}
catch (Exception ex)
{
Console.WriteLine($"停止服务器错误: {ex.Message}");
}
}
static void Main(string[] args)
{
Console.Title = "P2P协调服务器";
Console.WriteLine("=== P2P协调服务器 ===");
Console.WriteLine("用于远程桌面直连");
Console.WriteLine("端口: " + ServerPort);
Console.WriteLine(new string('=', 50));
var server = new P2PCoordinator();
server.Start();
}
}