我需要打开一些TCP端口,我想在所有端口都打开时发出信号,但这些任务无法完成,因为他们正在侦听传入的tcp数据包。
public partial class TcpServer
{
protected override void Init()
{
var ports = Enumerable.Range(17001, 32);
List<Task> tasks = new List<Task>();
foreach (int port in ports)
{
tasks.Add(Task.Run(() => new Listener(port)));
}
Task.WaitAll(tasks.ToArray()); //this will never complete
Console.WriteLine("Server ready!"); //I want to signal this when every port is opened
}
}
public class Program
{
public static void Main(string[] args)
{
var task = Task.Run(() => new TcpServer().Init());
Tasks.WaitAll(task);
}
}
public class Listener
{
public Listener(int port)
{
_puerto = port;
Escuchar(port);
}
private void Escuchar(int port)
{
listener = new TcpListener(IPAddress.Parse(GetLocalIPAddress()), port);
listener.Start();
Console.WriteLine($"Listening at port {_puerto}");
var error = false;
while (!error)
{
try
{
TcpClient client = listener.AcceptTcpClient(); //blocks here waiting for incoming packet
var stream = new StreamReader(client.GetStream());
var data = stream.ReadToEnd();
Evento evento = Parsear(data);
evento.Procesar();
}
catch (Exception e)
{
listener.Stop();
error = true;
}
}
Escuchar(port);
}
}
当所有端口都打开并准备好侦听传入的数据包时,我想发出控制台信号Console.WriteLine(&#34; Server ready!&#34;);
答案 0 :(得分:0)
最简单的方法可能是不要在一个函数中完成所有操作。将端口的开口移动到构造函数,例如:
var ports = Enumerable.Range(17001, 32);
var listeners = ports.AsParallel(port => new Listener(port)).ToList();
Console.WriteLine("Server ready!");
var listeningTasks = listeners.Select(listener => Task.Run(listener.Listen)).ToArray();
// now this line will block
Task.WaitAll(listeningTasks);
对听众稍作修改:
public class Listener
{
public Listener(int port)
{
_puerto = port;
listener = new TcpListener(IPAddress.Parse(GetLocalIPAddress()), port);
listener.Start();
Console.WriteLine($"Listening at port {_puerto}");
}
public void Listen()
{
var error = false;
while (!error)
{
try
{
TcpClient client = listener.AcceptTcpClient(); //blocks here waiting for incoming packet
var stream = new StreamReader(client.GetStream());
var data = stream.ReadToEnd();
Evento evento = Parsear(data);
evento.Procesar();
}
catch (Exception e)
{
listener.Stop();
error = true;
}
}
Listen();
}
}