我需要使用TcpListener监听多个端口,我需要TcpListener接受多个连接并分别处理每个端口,这是我写的代码,但是你看到它只是听第一个端口然后转到{{1}并监听到该端口的所有连接。任何想法我怎么能听多个连接的多个端口?
while(true)
和
private static async Task TcpServerAsync()
{
try
{
IPAddress ip;
if (!IPAddress.TryParse(ConfigurationManager.AppSettings["ipAddress"], out ip))
{
Console.WriteLine("Failed to get IP address, service will listen for client activity on all network interfaces.");
ip = IPAddress.Any;
}
foreach (Ports port in Ports.GetValues(typeof(Ports)))
{
Log.Info("Starting listener...");
var tcpListener = new TcpListener(ip, (int)port);
tcpListener.Start();
Log.Info("Listening...");
var startTimeSpan = TimeSpan.Zero;
var periodTimeSpan = TimeSpan.FromSeconds(10000000);
while (true)
{
TcpClient client = await tcpListener.AcceptTcpClientAsync();
client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, 1);
HandleByPortNumber(client, (int)port);
}
}
}
catch (Exception ex)
{
Log.Info("Error Happened : " + ex + ex.InnerException);
}
}
和
public static void HandleByPortNumber(TcpClient client , int portNumber)
{
switch (portNumber)
{
case (int)Ports.Teltonica:
var cw = new Teltonika.TcpClientService(client);
ThreadPool.UnsafeQueueUserWorkItem(x => ( (Teltonika.TcpClientService)x).Run(), cw);
break;
case (int)Ports.OBDTracker:
break;
}
}
答案 0 :(得分:2)
这是删除了附加功能(日志记录等)的实现。经过测试和工作。这里要解决的问题是如何从Task映射回其侦听器和端口号。显然,我的端口号列表不会对你有用,但除此之外它应该可行。您还需要替换Tuple<>使用自定义类,以提高可读性。
IDictionary<Task<TcpClient>, Tuple<int, TcpListener>> tcpListeners = new Dictionary<Task<TcpClient>, Tuple<int, TcpListener>>();
foreach (var port in Enumerable.Range(20000, 5))
{
var tcpListener = new TcpListener(IPAddress.Any, port);
tcpListener.Start();
var task = tcpListener.AcceptTcpClientAsync();
var tcpListenerPortPair = new Tuple<int, TcpListener>(port, tcpListener);
tcpListeners.Add(task, tcpListenerPortPair);
}
Task<TcpClient> tcpClientTask;
while ((tcpClientTask = await Task.WhenAny(tcpListeners.Keys)) != null)
{
var tcpListenerPortPair = tcpListeners[tcpClientTask];
var port = tcpListenerPortPair.Item1;
var tcpListener = tcpListenerPortPair.Item2;
tcpListeners.Remove(tcpClientTask);
// This needs to be async. What to do with its Task?
// It cannot be awaited here.
var handlerTask = HandleByPortNumber(tcpClientTask.Result, port);
var task = tcpListener.AcceptTcpClientAsync();
tcpListeners.Add(task, tcpListenerPortPair);
}