因为要写一个网络程序要用到UDP协议,UDP这东西比较麻烦,又不像TCP一样提供可靠的连接,发送接收的超时实在不好设计,最后只要用Timer来检测有没有想要的数据包
-
_#,不过这不是这次的重点,重点是怎么建立一种高效的UDP机制来实时接收服务器发送过来的数据包.
CodeProject上有个例子是开个线程去同步接收,这样倒是可以满足我的程序需求,不过实际中遇到几个问题:
1 .程序开销大,内存狂飙,接一次数据就要重新开一次线程
2 .由于主界面和底层是完全隔离只是通过中间的接口来通讯,导致线程总是不能正常的结束,程序结束后还有一个进程在那里不知道干什么.
于是翻阅MSDN,查找自己以前写的代码,最后还是决定用异步来接收,MSDN上UDP异步的例子不太好,有点敷衍的意思,用异步很好的解决了以上的问题,高效完成效率,代码如下:
CodeProject上有个例子是开个线程去同步接收,这样倒是可以满足我的程序需求,不过实际中遇到几个问题:
1 .程序开销大,内存狂飙,接一次数据就要重新开一次线程
2 .由于主界面和底层是完全隔离只是通过中间的接口来通讯,导致线程总是不能正常的结束,程序结束后还有一个进程在那里不知道干什么.
于是翻阅MSDN,查找自己以前写的代码,最后还是决定用异步来接收,MSDN上UDP异步的例子不太好,有点敷衍的意思,用异步很好的解决了以上的问题,高效完成效率,代码如下:
- UdpClient qq_client; //Udp客户端
- qq_client = new UdpClient();
- IPEndPoint remoteQQEP = new IPEndPoint(remotehost, remoteport);
- qq_client.Connect(remoteQQEP);
- AsyncCallback GetRecvBuffer = new AsyncCallback(ReceiveCallback);
- qq_client.BeginReceive(GetRecvBuffer, null);
- 这里用一个GetRecvBuffer的回掉来实现异步
- private void ReceiveCallback(IAsyncResult ar)
- {
- try
- {
- lock (this)
- {
- byte[] recvbytes = qq_client.EndReceive(ar, ref remoteQQEP);
- //QQFunction.DebugDump(recvbytes);
- if (recvbytes[0] != QQDef.QQ_IM_HEAD && recvbytes[0] != 0x03)
- {
- //非QQ数据包
- return;
- }
- switch (Pop16(recvbytes, 3))
- {
- case QQDef.QQ_REQUEST_TOKEN:
- DoGetToken(recvbytes);
- break;
- case QQDef.QQ_REQUEST_LOGIN:
- DoGetLogin(recvbytes);
- break;
- case QQDef.QQ_GET_ONLINE_FRIEND:
- DoGetOnline(recvbytes);
- break;
- case QQDef.QQ_KEEP_ALIVE:
- CheckAlive(recvbytes);
- break;
- case QQDef.QQ_SEND_IM_MSG:
- // Do SomeThing
- break;
- case QQDef.QQ_RECV_IM_MSG:
- DoRecvMsg(recvbytes);
- break;
- default:
- QQFunction.DebugDump("UnKnow Command");
- QQFunction.DebugDump(recvbytes);
- break;
- }
- }
- lock (this)
- {
- AsyncCallback GetRecvBuffer = new AsyncCallback(ReceiveCallback);
- qq_client.BeginReceive(GetRecvBuffer, null);
- }
- }
- catch
- {
- }
- }
代码是不是很简单?功能是不是很强大?