C# 使用UDP多端口异步监听,请教高手,急用!~
我现在需要开发一个服务端的软件,用来给几百个客户端提供服务,需要监听多个端口(10个左右),
当有数据发来时,由程序处理并提供数据返回给客户端,现在使用的是UdpClient对象,为了尽可能多地收到数据包,目前的程序采用异步监听多个端口,收到数据就放到一个队列里面,由另外几个线程来处理,并返回数据。但是,返回数据时需要同一个UdpClient对象的send方法,重新实例化一个,终端就收不到了
出现的异常是在监听时:远程主机强迫关闭了一个现有的连接。
代码如下
private readonly Queue<PackageState> RecQueue = new Queue<PackageState>(); //接收队列
private void btnStart_Click(object sender, EventArgs e)
{
string[] ports = PAK.config.ports;//监听端口集合
shouldStop = false;
//创建处理线程
threadSend = new Thread[5];
for (var i = 0; i < 5; i++)
{
threadSend[i] = new Thread(new ThreadStart(readQueue));
threadSend[i].IsBackground = true;
threadSend[i].Start();
Thread.Sleep(50);
}
//开始监听端口
foreach (string port in PAK.config.ports)
{
try
{
int p = Convert.ToInt32(port);
UdpClient uc = new UdpClient(p);
listen(uc);
tsslText.Text += p.ToString() + " ";
}
catch (Exception ex)
{
tsslText.Text = ex.Message;
continue;
}
}
}
//开始异步监听端口
private void listen(UdpClient uc)
{
IPEndPoint remoteHost = new IPEndPoint(IPAddress.Any, 0);
PackageState ps = new PackageState();//数据包状态对象
ps.end = remoteHost;
ps.uc = uc;
IAsyncResult iar = ps.uc.BeginReceive(new AsyncCallback(this.RecieveCallBack), ps);
allDone.Set();
}
//监听回调方法
private void RecieveCallBack(IAsyncResult asynchronousResult)
{
PackageState ps = (PackageState)asynchronousResult.AsyncState;
try
{
byte[] bt = ps.uc.EndReceive(asynchronousResult, ref ps.end);
ps.BufferData = bt;
lock (locker)
{
RecQueue.Enqueue(ps);//数据保存到队列
receCount++;//接收数据计数+1
}
lblCount.Text = receCount.ToString();//显示接收个数
ps.uc.BeginReceive(new AsyncCallback(RecieveCallBack), asynchronousResult.AsyncState);//继续异步监听
}
catch (Exception o)
{
this.tsslText.Text = o.Message;//显示异常信息
}
}
//处理数据方法
private void readQueue()
{
while (!shouldStop)
{
PackageState ps;//创建状态对象
lock (locker)
{
if (RecQueue.Count > 0)
{
ps = RecQueue.Dequeue();//取出状态对象
}
else
{
Thread.Sleep(PAK.config.readsleep);
continue;
}
}
string receivestr = Encoding.Default.GetString(ps.BufferData);
string[] response =getPackage(receivestr);//处理并得到响应数据包
foreach (string sendstr in response)
{
byte[] senddata = Encoding.Default.GetBytes(sendstr);
//异步发送
IAsyncResult r = (IAsyncResult)ps.uc.BeginSend(senddata, senddata.Length, ps.end, new AsyncCallback(this.SendPackageCallBack), ps); // 发出异步请求
allDone.Reset();
}
Thread.Sleep(PAK.config.readsleep);
}
}
//发送数据回调方法
private void SendPackageCallBack(IAsyncResult asynchronousResult)
{
try
{
PackageState ps = (PackageState)asynchronousResult.AsyncState;
int a = ps.uc.EndSend(asynchronousResult);
sendCount++;//发送计数+1
}
catch (Exception e)
{
this.tsslText.Text = e.Message;
}
}
这样写有什么问题吗?有没有更好的办法,请高手指点~~