【问题标题】:C# TCP server listen to multiple portsC# TCP 服务器监听多个端口
【发布时间】:2021-07-10 12:03:04
【问题描述】:

我正在使用下面的代码,该代码由 Rick Miller(Pulp Free Press)创建。我需要在多个端口上接收数据,为每个端口打开独立的线程。

尝试使用 new Thread(Listener(10000)).Start();但它没有按预期工作。

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;

public class MultiThreadedEchoServer {
public static void Main() {
    Listener(10000);
}

private static void Listener(int port) {
    TcpListener listener = null;
    try {
        listener = new TcpListener(IPAddress.Any, port);
        listener.Start();
        Console.WriteLine("MultiThreadedEchoServer started...");
        while (true) {
            Console.WriteLine("Waiting for incoming client connections...");
            TcpClient client = listener.AcceptTcpClient();
            Console.WriteLine("Accepted new client connection...");
            Thread t = new Thread(ProcessClientRequests);
            t.Start(client);
        }
    } catch (Exception e) {
        Console.WriteLine(e);
    } finally {
        if (listener != null) {
            listener.Stop();
        }
    }
}

private static void ProcessClientRequests(object argument) {
    TcpClient client = (TcpClient)argument;
    client.ReceiveBufferSize = 4096;

    try {
        StreamReader reader = new StreamReader(client.GetStream());
        StreamWriter writer = new StreamWriter(client.GetStream());
        string s = String.Empty;
        while (!(s = reader.ReadLine()).Equals("Exit") || (s == null)) {
            Console.WriteLine("From client -> " + s);
            writer.WriteLine("From server -> " + s);
            writer.Flush();
        }
        reader.Close();
        writer.Close();
        client.Close();
        Console.WriteLine("Closing client connection!");
    } catch (IOException) {
        Console.WriteLine("Problem with client communication. Exiting thread.");
    } finally {
        if (client != null) {
            client.Close();
        }
    }
}
}

【问题讨论】:

  • 你删除了你昨天发的帖子吗?我给出了使用异步套接字的答案,并在您收到消息的同一个套接字上发回。
  • 是的,我这样做是因为我找到了解决方案。现在我有一个新问题。程序监听单个端口(10000),我需要修改代码使其监听多个端口。
  • 重要问题:如果您在谈论多个端口,我认为您将希望运行多个入站连接;显示的代码使用每个连接的线程,这对于任何不平凡的规模都是可怕的。那么:是否您正在尝试做任何规模不小的事情?至于实际问题:“每个端口使用单独的侦听器” - 完成。我同意@jdweng 的观点,无论哪种方式,异步都是解决问题的方法,但老实说:我只是在这里使用 Kestrel,让它担心套接字层,我会告诉它我关心的端口.
  • 例如,这是一个基于 Kestrel 的玩具(意思是:不严重,不要在生产中使用)redis 服务器 - 这里使用自定义监听 6379(redis 端口)的原始套接字 IO处理程序和 5000 上的基本 http 服务器,但您可以看到为您想要的任何内容添加额外的端口是多么容易:github.com/StackExchange/StackExchange.Redis/blob/main/toys/…
  • nit:“你删除了你昨天发的帖子吗?” /“是的,我这样做是因为我找到了解决方案。” - 真正好的做法是将您的解决方案添加到您的问题中并将其留在那里,以像我们试图帮助您一样的方式帮助其他人

标签: c# network-programming tcplistener


【解决方案1】:

尝试使用new Thread(Listener(10000)).Start();,但没有按预期工作。

表达式Listener(10000) 返回void,因此您不能将其用作参数;你需要的是ThreadStart,所以:

new Thread(() => Listener(10000)).Start();

对于少数端口,thread-per-port 并不算太糟糕,但我要强调的是,显示的代码是 thread-per-client,这将非常大地扩展;这不是编写服务器的好方法,除了只有少数(例如:少于 10 个)表现良好的客户端的琐碎事情。

【讨论】:

  • 谢谢!这正是我所需要的。我正在研究用于连接 GPS 跟踪器的 TCP 侦听器。程序将等待 100-500 个不同端口上的连接,每个端口专用于唯一设备。每个端口将接收数千个数据包。所以现在我正在寻找合适的解决方案。
  • @LastCodeLine 我们在这里谈论多少客户? 100-500 端口表示客户端数量非常多,在这种情况下:请立即停止使用线程 - 这不是可扩展的解决方案。现在,异步套接字 IO 是可能的,但 API 很糟糕 - 老实说:Kestrel 和管道是这里的方法。请参阅我在主要问题的评论中链接到的代码,或我的多部分博客系列:blog.marcgravell.com/2018/07/pipe-dreams-part-1.html
  • 我非常同意 Marc Gravell 的观点。拥有 100 甚至 500 个线程是一种糟糕的设计,它会拖累您的程序性能。就像他提到的那样,为什么不使用像 Kestrel 这样的合适的服务器,它已经解决了处理数百个客户端的所有问题和挑战?
  • @LastCodeLine 不,不是;该 API 是旧版的;对于 TCP 服务器,我会 100% 说“使用 Kestrel”;对于 UDP,有更好的方法 - 如果您让我知道您的 GitHub(可能是通过电子邮件),我会将您添加到显示此内容的私人存储库中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-07
  • 1970-01-01
  • 2013-03-11
  • 1970-01-01
  • 2019-02-20
  • 1970-01-01
  • 2020-08-31
相关资源
最近更新 更多