我正在使用多线程system.net.socket来监听单个端口。我想捕获来自多个客户端的同时请求。这是我的样本:
private static ManualResetEvent _manualResetEvent = new ManualResetEvent(false);
public class Program
{
static void Main(string[] args)
{
Program program = new Program();
Thread threadListener = new Thread(program.StartListening);
threadListener.Start();
}
private void StartListening()
{
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, Convert.ToInt32(ConfigurationManager.AppSettings["httpPort"].ToString()));
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Blocking = false;
listener.Bind(localEndPoint);
listener.Listen(10);
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
}
public static void AcceptCallback(IAsyncResult ar)
{
_manualResetEvent.Set();
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
}
private void ReceiveCallback(IAsyncResult result)
{
StateObject state = null;
Socket handler = null;
try
{
state = (StateObject)result.AsyncState;
handler = state.workSocket;
int numBytesReceived = handler.EndReceive(result);
if (!handler.Connected)
{
handler.Close();
return;
}
if (numBytesReceived > 0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, numBytesReceived));
string[] lines = state.sb.ToString().Split('\n');
if (lines[lines.Length-1] == "EOF")
{
// Do something according to client request
}
else
{
// We didn't receive all data. Continue receiving...
handler.BeginReceive(state.buffer, 0, state.buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), state);
}
}
}
catch (ObjectDisposedException ex)
{
// Don't care
}
catch (Exception ex)
{
if (handler != null)
{
handler.Close();
}
}
}
}
public class StateObject
{
public Socket workSocket = null;
public const int BufferSize = 256;
public byte[] buffer = new byte[BufferSize];
public StringBuilder sb = new StringBuilder();
}
问题是我无法仅使用这些代码来运行应用程序。如果我运行此应用程序并捕获客户端请求,我的ReceiveCallBack方法可以正常工作,并且应用程序在成功执行后停止。
我可以使用此MSDN link中的示例代码来保持我的应用程序活跃。它在StartListening方法中使用while循环,如下所示:
while (true)
{
allDone.Reset();
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
allDone.WaitOne();
}
但似乎MSDN为阻塞侦听器设计了此代码。我的意思是它不允许同时连接。所以这对我来说不合适。
我必须阻止我的应用程序在执行我的代码后停止而不在MSDN示例中使用while循环。我必须让它继续运行并持续监听多个同时连接。
那么如何让该应用程序继续运行?
由于
答案 0 :(得分:0)
问题在于没有线程可以让你的进程保持活跃状态。在很短的时间内,只有线程池线程在运行并且运行时关闭。
从Main开始一个新线程什么也没做。告诉我你认为这应该实现的目标,我将澄清误解。 Main应该看起来像StartListening(); Thread.Sleep(Timeout.Infinite);
。 (反直观!)
除了代码是可行的,虽然质量低。我有太多问题需要详细评论。将此内容提交给Codereview SE。