当每个端口接受多个连接时,如何侦听多个TCP端口

时间:2018-04-15 08:43:46

标签: c# .net sockets tcplistener

我需要使用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, SocketOptionNam‌​e.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;
        }
    }

1 个答案:

答案 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);
}