C# 如何设置TcpListener以始终侦听和接受多个连接?
这是我的服务器应用程序:C# 如何设置TcpListener以始终侦听和接受多个连接?,c#,networking,tcplistener,C#,Networking,Tcplistener,这是我的服务器应用程序: public static void Main() { try { IPAddress ipAddress = IPAddress.Parse("127.0.0.1"); Console.WriteLine("Starting TCP listener..."); TcpListener listener = new TcpListener(ipAddress,
public static void Main()
{
try
{
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
Console.WriteLine("Starting TCP listener...");
TcpListener listener = new TcpListener(ipAddress, 500);
listener.Start();
while (true)
{
Console.WriteLine("Server is listening on " + listener.LocalEndpoint);
Console.WriteLine("Waiting for a connection...");
Socket client = listener.AcceptSocket();
Console.WriteLine("Connection accepted.");
Console.WriteLine("Reading data...");
byte[] data = new byte[100];
int size = client.Receive(data);
Console.WriteLine("Recieved data: ");
for (int i = 0; i < size; i++)
Console.Write(Convert.ToChar(data[i]));
Console.WriteLine();
client.Close();
}
listener.Stop();
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.StackTrace);
Console.ReadLine();
}
}
publicstaticvoidmain()
{
尝试
{
IPAddress=IPAddress.Parse(“127.0.0.1”);
WriteLine(“正在启动TCP侦听器…”);
TcpListener侦听器=新的TcpListener(ipAddress,500);
listener.Start();
while(true)
{
WriteLine(“服务器正在侦听”+listener.LocalEndpoint);
Console.WriteLine(“等待连接…”);
Socket client=listener.AcceptSocket();
Console.WriteLine(“已接受连接”);
Console.WriteLine(“读取数据…”);
字节[]数据=新字节[100];
int size=client.Receive(数据);
Console.WriteLine(“接收数据:”);
对于(int i=0;i
正如您所见,它总是在工作时侦听,但我想指定我希望应用程序能够侦听并同时支持多个连接
我如何修改此选项,以便在接受多个连接的同时不断侦听
这样做将允许侦听套接字接受并处理多个连接,因为您正在侦听的线程在等待传入数据时不再阻塞或等待
while(true)
{
Socket client=listener.AcceptSocket();
Console.WriteLine(“已接受连接”);
var childSocketThread=新线程(()=>
{
字节[]数据=新字节[100];
int size=client.Receive(数据);
Console.WriteLine(“接收数据:”);
对于(int i=0;i
我今天遇到了一个类似的问题,并这样解决了它:
while (listen) // <--- boolean flag to exit loop
{
if (listener.Pending())
{
Thread tmp_thread = new Thread(new ThreadStart(() =>
{
string msg = null;
TcpClient clt = listener.AcceptTcpClient();
using (NetworkStream ns = clt.GetStream())
using (StreamReader sr = new StreamReader(ns))
{
msg = sr.ReadToEnd();
}
Console.WriteLine("Received new message (" + msg.Length + " bytes):\n" + msg);
}
tmp_thread.Start();
}
else
{
Thread.Sleep(100); //<--- timeout
}
}
基本思想是,侦听器套接字总是在给定的IP和端口号上侦听。当有连接请求时,侦听器接受连接,并使用tcpclient对象获取远程端点,直到连接关闭或丢失。如何异步设置它(而不为每个客户端旋转新线程?)@mrdyprosium scalability显然。你说得很明显,所以也许我对这个话题的理解程度很低。。。但为什么异步比线程更具可伸缩性?@mrdyprosium因为为操作系统创建和管理线程的成本很高,因此为每个客户端旋转一个线程的成本很高。除此之外,您为每个客户机创建的线程将不做任何事情,大多数只是等待从客户机获取一些东西。@SHM不是2年后回复的那个人,但为了让异步进程继续进行,在某个时候必须建立一个线程,因此,必须有人假脱机一个线程。即使在另一台机器的电线上,也会打开一条线等待响应。我不明白您如何建立异步进程(例如,任务仍然是线程)。指定
127.0.0.1
是否将侦听套接字限制为仅在本地计算机上工作?公共网络上的设备能够访问此侦听套接字吗?为什么使用新字节[100]代码>数组?这是从客户端发送的数据大小吗?@barteloma这是很久以前的事了,我不记得了,但它可能只是一个神奇的数字。一般来说,当我想管理来自外部的监听时,我也会使用此解决方案,并可能正确地停止它。我面临的唯一问题是,如果设置为高,使用sleep命令会产生太多的延迟,如果设置为低,则会消耗cpu。有什么办法可以解决这个问题吗?我相信最好的解决方案是结合使用async/await和“Task.Delay(…)”。当我可以访问我的计算机时,我将尝试进一步阐述。太好了,让我们看看它是如何工作的。我的另一个想法是继续使用AcceptCpcClient而不嵌套到睡眠等待循环中,并在另一个单独的线程中启动它,然后在想要完成侦听时强制终止它。然后它抛出一个必须处理的异常。丑陋,但在速度方面似乎是最有效的,只是想知道是否有类似但更好的解决方案。我更新了答案,使用“Task.Delay(…)”包含异步代码。使用任务的异步编程被认为是基于线程的代码构造的“继承者”。最好的方法是在while循环中等待listener.AcceptTcpClientAsync。如果希望能够从外部关闭侦听套接字,则只需使用取消令牌关闭套接字并捕获AcceptCpclientAsync()引发的套接字异常
while (listen) // <--- boolean flag to exit loop
{
if (listener.Pending())
{
Thread tmp_thread = new Thread(new ThreadStart(() =>
{
string msg = null;
TcpClient clt = listener.AcceptTcpClient();
using (NetworkStream ns = clt.GetStream())
using (StreamReader sr = new StreamReader(ns))
{
msg = sr.ReadToEnd();
}
Console.WriteLine("Received new message (" + msg.Length + " bytes):\n" + msg);
}
tmp_thread.Start();
}
else
{
Thread.Sleep(100); //<--- timeout
}
}
private static TcpListener listener = .....;
private static bool listen = true; // <--- boolean flag to exit loop
private static async Task HandleClient(TcpClient clt)
{
using NetworkStream ns = clt.GetStream();
using StreamReader sr = new StreamReader(ns);
string msg = await sr.ReadToEndAsync();
Console.WriteLine($"Received new message ({msg.Length} bytes):\n{msg}");
}
public static async void Main()
{
while (listen)
if (listener.Pending())
await HandleClient(await listener.AcceptTcpClientAsync());
else
await Task.Delay(100); //<--- timeout
}