internal Peer() { client = new TcpClient(); _len = 0; _recvdata = new byte[_len]; _recvbuffers = ReplacableQueue <ArraySegment <byte> > .Synchronized(new ReplacableQueue <ArraySegment <byte> >(delegate(ArraySegment <byte> item) { return(item.Array.Length); })); _id = client.Client.Handle.ToInt32(); _read = 0; _check = false; _lastdisconnectcheck = DateTime.MinValue; }
public void Create(INetEvent hander, int nPort, int nCount, bool encrypt) { handler = hander; server = new TcpListener(IPAddress.Any, nPort); server.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); server.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); server.Server.LingerState = new LingerOption(false, 0); server.Server.NoDelay = true; server.Server.Blocking = false; op = Queue.Synchronized(new Queue(nCount)); peers = new Dictionary <int, Peer>(nCount); count = nCount; locker = new RWLock(); sendbuffers = ReplacableQueue <SendBuff> .Synchronized(new ReplacableQueue <SendBuff>(delegate(SendBuff item) { return(item.buff.Length); })); ThreadPool.SetMaxThreads(100, 100); ThreadPool.SetMinThreads(10, 10); Thread t = new Thread(delegate() { while (running) { if (peers.Count > 0) { Peer[] clients; locker.AcquireReaderLock(Timeout.Infinite); clients = new Peer[peers.Count]; peers.Values.CopyTo(clients, 0); locker.ReleaseReaderLock(); for (int i = 0; i < clients.Length; ++i) { Peer c = clients[i]; if (!c.Connected) { continue; } try { Socket s = c.client.Client; if (s.Poll(0, SelectMode.SelectRead) && s.Available > 0) { byte[] recvbuffer = new byte[recvBufferSize]; if (!s.Connected) { continue; } if (c._check) { continue; } if (c._read > 0) { continue; } Interlocked.Increment(ref c._read); try { s.BeginReceive(recvbuffer, 0, recvBufferSize, SocketFlags.None, delegate(IAsyncResult ar) { try { if (s == null || !s.Connected) { return; } int readSize = s.EndReceive(ar); byte[] buf = new byte[readSize]; Buffer.BlockCopy(recvbuffer, 0, buf, 0, readSize); c.AddBuffer(buf); } catch (Exception ex) { Debug.WriteLine(ex.Message); Debug.WriteLine(ex.StackTrace); f d = delegate() { Close((ushort)((ar.AsyncState as object[])[0] as Peer)._id); }; op.Enqueue(d); } finally { Interlocked.Decrement(ref c._read); } }, null); } catch { Interlocked.Decrement(ref c._read); throw; } } } catch (SocketException) { f d = delegate() { Close((ushort)c._id); }; op.Enqueue(d); } catch (ObjectDisposedException) { } catch (Exception ex) { Debug.WriteLine(ex.Message); Debug.WriteLine(ex.StackTrace); f d = delegate() { Close((ushort)c._id); }; op.Enqueue(d); } } } Thread.CurrentThread.Join(1); } }); Thread u = new Thread(delegate() { while (running) { if (peers.Count > 0) { Peer[] clients; locker.AcquireReaderLock(Timeout.Infinite); clients = new Peer[peers.Count]; peers.Values.CopyTo(clients, 0); locker.ReleaseReaderLock(); for (int i = 0; i < clients.Length; ++i) { Peer c = clients[i]; try { if (!c.Connected) { continue; } if (c._recvbuffers.Count == 0) { continue; } int copylen; ArraySegment <byte> buffer; byte[] data; if (c._len <= 0) { buffer = c._recvbuffers.Peek(); data = new byte[sizeof(int)]; if (buffer.Count < data.Length) { c._recvbuffers.Dequeue(); continue; } Buffer.BlockCopy(buffer.Array, buffer.Offset, data, 0, data.Length); c._len = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 0)); if (c._len <= 0) { c._recvbuffers.Dequeue(); continue; } c._recvdata = new byte[c._len]; copylen = 0; if (buffer.Count > data.Length) { copylen = buffer.Count - data.Length; if (copylen > c._len) { copylen = c._len; Buffer.BlockCopy(buffer.Array, data.Length, c._recvdata, 0, copylen); Buffer.BlockCopy(buffer.Array, data.Length + copylen, buffer.Array, 0, buffer.Count - (data.Length + copylen)); buffer = new ArraySegment <byte>(buffer.Array, 0, buffer.Count - (data.Length + copylen)); c._recvbuffers.Set(buffer); } else { Buffer.BlockCopy(buffer.Array, data.Length, c._recvdata, 0, copylen); c._recvbuffers.Dequeue(); } } c._len -= copylen; } while (c._len > 0 && c._recvbuffers.Count > 0) { buffer = c._recvbuffers.Peek(); if (buffer.Count <= c._len) { copylen = buffer.Count; Buffer.BlockCopy(buffer.Array, 0, c._recvdata, 0, copylen); c._recvbuffers.Dequeue(); } else { copylen = c._len; Buffer.BlockCopy(buffer.Array, 0, c._recvdata, 0, copylen); Buffer.BlockCopy(buffer.Array, copylen, buffer.Array, 0, buffer.Count - copylen); buffer = new ArraySegment <byte>(buffer.Array, 0, buffer.Count - copylen); c._recvbuffers.Set(buffer); } c._len -= copylen; if (c._recvbuffers.Count == 0) { break; } } if (c._len <= 0) { c._len = 0; data = (byte[])c._recvdata.Clone(); f d = delegate() { handler.OnRecv((ushort)c._id, data); }; op.Enqueue(d); } } catch (Exception ex) { Debug.WriteLine(ex.Message); Debug.WriteLine(ex.StackTrace); f d = delegate() { Close((ushort)c._id); }; op.Enqueue(d); } } } Thread.CurrentThread.Join(1); } }); t.IsBackground = true; u.IsBackground = true; running = true; t.Start(); u.Start(); server.Start(nCount); }