如何使用线程池来处理新线程中的每个连接
问题描述:
我有一个简单的服务器,它等待客户端连接,读取传入流并发回消息。我想要做的是每个连接都由一个单独的线程处理。这是我第一次使用C#中的套接字和线程,而且我发现的大多数例子都非常令人困惑,所以任何帮助或简单的例子都会非常感谢。如何使用线程池来处理新线程中的每个连接
这是我现在所拥有的。
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
[STAThread]
static void Main(string[] args)
{
TestServer ts = new TestServer();
ts.Start();
}
class TestServer
{
private readonly int port = 48888;
private readonly IPAddress ip = IPAddress.Parse("127.0.0.1");
private TcpListener listener;
public TestServer()
{
this.listener = new TcpListener(this.ip, this.port);
}
public void Start()
{
this.listener.Start();
Console.WriteLine("Server Running...");
Socket s;
Byte[] incomingBuffer;
int bytesRead;
Byte[] Message;
while (true)
{
s = this.listener.AcceptSocket();
incomingBuffer = new Byte[100];
bytesRead = s.Receive(incomingBuffer);
string message = "Hello from the server";
Message = Encoding.ASCII.GetBytes(message.ToCharArray());
s.Send(Message);
}
}
}
答
试试这个:
public void Start()
{
this.listener.Start();
Console.WriteLine("Server running...");
while (true)
{
Socket s = this.listener.AcceptSocket();
ThreadPool.QueueUserWorkItem(this.WorkMethod, s);
}
}
private void WorkMethod(object state)
{
using (Socket s = (Socket)state)
{
byte[] buffer = new byte[100];
int count = s.Receive(buffer);
string message = "Hello from the server";
byte[] response = Encoding.ASCII.GetBytes(message);
s.Send(response);
}
}
答
使用线程池。您可以手动使用实例化线程,但由于您可能有大量连接,因此threadpoool会更高效。
System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(processMessage), socket);
processMessage是处理消息的方法。每个连接将有一个线程。其实真的很简单。
答
不能直接回答你的问题,但是...
线程池是不是“每个连接新的线程”,它们是关于有螺纹的一些有意义的数量(有一些关系到核心数量上的框)已经在运行并等待工作。这个“工作”通过一个或多个队列由生产者线程(接受你的情况下的连接的那个线程)给予池。
请注意,这并不总是最好的解决方案。看看C10K和Hight Performance Server Architecture页面。
ThreadPool.QueeuUserWorkItem(this.processMessage,socket)和ThreadPool.QueueUserWorkItem(new WaitCallBack(processMessage),socket)有什么区别? – Tester101 2009-11-12 19:48:44
@ Tester101:第一个参数必须是WaitCallback类型的委托。你不能直接在那里传递一个方法。所以我将这个方法包装在委托中并通过了它。作为第一个参数,你不能直接传递processMessage。 – bobbyalex 2009-11-13 04:43:51