C# 使用UDP多端口异步监听,请教高手,急用!~

feiniaon 2012-01-18 09:51:40
我现在需要开发一个服务端的软件,用来给几百个客户端提供服务,需要监听多个端口(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;
}
}

这样写有什么问题吗?有没有更好的办法,请高手指点~~
...全文
941 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
NdscFaineant 2012-01-18
  • 打赏
  • 举报
回复
“IPEndPoint remoteHost = new IPEndPoint(IPAddress.Any, 0);”
所有的UdpClient的远程IPEndPoint发送到本地,而且端口为0?这样好像无法收发数据。

远程端口使用uc.Client.RemoteEndPoint
改为IPEndPoint remoteHost = uc.Client.RemoteEndPoint试试。
_老吴 2012-01-18
  • 打赏
  • 举报
回复
那那你就只能开多线程监听了

110,477

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧