首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

IO完成端口是怎么做的

2012-03-25 
IO完成端口是如何做的长连接的简单模型大概是这样的C# codeprivate int _port 6868private const int _

IO完成端口是如何做的
长连接的简单模型大概是这样的

C# code
        private int _port = 6868;        private const int _maxPacket = 64;        private TcpListener _tcpl = null;        public string userip;        public Hashtable _transmit_tb = new Hashtable();        static void Main(string[] args)        {            Listen l = new Listen();            try            {                l.startup();            }            catch (Exception) {  }        }        public void startup()        {            IPAddress _ip = Dns.GetHostAddresses(Dns.GetHostName())[0];            _tcpl = new TcpListener(_ip, _port);            _tcpl.Start();            Console.WriteLine(string.Format("the server ip is {0},and the port is {1}", _ip, _port));            Console.WriteLine("server has been started,is listening...");            while (true)            {                byte[] packetBuff = new byte[_maxPacket];                Socket newClient = _tcpl.AcceptSocket();                IPEndPoint ip = (IPEndPoint)newClient.RemoteEndPoint;                //userip = ip.Address.ToString().TrimEnd() + ":" + ip.Port;                userip = ip.Address.ToString().TrimEnd();                if (_transmit_tb.Count != 0 && _transmit_tb.ContainsKey(userip))                {                    _transmit_tb.Remove(userip);                    _transmit_tb.Add(userip, newClient);                }                else                    _transmit_tb.Add(userip, newClient);                string svrlog = string.Format("new ip {0} at {1} is connected,current online number is {2}", userip + ":" + ip.Port, DateTime.Now, _transmit_tb.Count);                Console.WriteLine(svrlog);                Thread clientthread = new Thread(new ParameterizedThreadStart(threadfun));                clientthread.Start(userip);                clientthread.IsBackground = true;                Thread.Sleep(200);            }        }        private void threadfun(object obj)        {            Socket clientsocket = _transmit_tb[obj] as Socket;            while (true)            {                try                {                    if (clientsocket == null || clientsocket.Available < 1)                    {                        Thread.Sleep(300);                        continue;                    }                    byte[] _cmdBuff = new byte[128];                    int size = clientsocket.Receive(_cmdBuff);                    //在这里处理收到的数据                    //向客户端发送数据                    clientsocket.Send(_cmdBuff);                }                catch (SocketException)                {                    _transmit_tb.Remove(obj);                    clientsocket.Close();                    Thread.CurrentThread.Abort();                }            }        }

在主线程里监听客户端连接请求,然后每个连接到服务器的用户都建立一个线程,在这个线程里再死循环收客户发来的数据包,做处理以后再回客户端数据包,这种模式显然用户很多的时候是不行的,太耗服务器资源。
请高手帮忙把这段代码改成IO完成端口的,可以接收同时5000人以上用户的连接。
请给详细代码,写上注释。

[解决办法]
http://topic.csdn.net/t/20040512/08/3056877.html
[解决办法]
其实C#的很多异步操作已经使用了IO Complemention,你只要简单的BeginReceive/EndReceive就可以了。.Net内部会帮你把IO Complemtion发送到线程池并调用你提供的回调函数。

比如下面的代码。
在实验中保持Server运行,同时运行多次Client,你可以发现.Net并不一定需要多个线程来服务多个客户,在保持快速响应的同时,尽可能复用可用线程(可能最终一个就够了):
C# code
// Server.csclass Server{    static void Main(string[] args)    {        TcpListener listener = new TcpListener(IPAddress.Any, 4567);        listener.Start();        while (true)        {            Socket socket = listener.AcceptSocket();            StateObject so = new StateObject() { socket = socket };            so.socket.BeginReceive(so.buffer, so.offset, StateObject.BUFFER_SIZE - so.offset, SocketFlags.None, AsyncCallback, so);        }    }            static void AsyncCallback(IAsyncResult ar)    {        Console.WriteLine("AsyncCallBack in managed thread " + Thread.CurrentThread.ManagedThreadId);        StateObject so = ar.AsyncState as StateObject;        int read = 0;        try        {            read = so.socket.EndReceive(ar);            so.offset += read;        }        catch (SocketException se)         {            Console.WriteLine(se.Message);        }        if (read == 0)        {            string msg = Encoding.UTF8.GetString(so.buffer, 0, so.offset);            Console.WriteLine(msg);        }        else        {            so.socket.BeginReceive(so.buffer, so.offset, StateObject.BUFFER_SIZE - so.offset, SocketFlags.None, AsyncCallback, so);        }    }    public class StateObject    {        public Socket socket = null;        public const int BUFFER_SIZE = 64*1024;        public byte[] buffer = new byte[BUFFER_SIZE];        public int offset = 0;    }} 

热点排行