private void SendQueue(NetHandlerImpl handler) { lock (workqueue) { if (!workindex.ContainsKey(handler)) { workindex.Add(handler, true); workqueue.Enqueue(handler); Monitor.Pulse(workqueue); } } if (workcount >= settings.worklimit) { return; } if (Interlocked.Increment(ref workcount) > settings.worklimit) { Interlocked.Decrement(ref workcount); return; } new Thread(delegate() { Thread.CurrentThread.Name = "Network Write"; while (running) { handler = null; lock (workqueue) { while (running) { if (workqueue.Count != 0) { handler = workqueue.Dequeue(); workindex.Remove(handler); break; } Monitor.Wait(workqueue); } } if (handler != null) { bool result; try { result = handler.Socket.Poll((int)settings.timeout * 1000, SelectMode.SelectWrite); } catch (ObjectDisposedException) { continue; } if (result) { if (!handler.SendReady()) { continue; } } lock (workqueue) { if (!workindex.ContainsKey(handler)) { workindex.Add(handler, true); workqueue.Enqueue(handler); } } } } }).Start(); }
public void Listen(int port, Action <NetHandler> callback) { if (!running) { throw new ObjectDisposedException(ToString()); } new Thread(delegate() { Thread.CurrentThread.Name = "Network Server"; TcpListener server = new TcpListener(IPAddress.Any, port); server.Start(); Control ctrl; lock (listens) { if (listens.TryGetValue(port, out ctrl)) { ctrl.running = true; } else { ctrl = new Control { running = true }; listens[port] = ctrl; } } ctrl.action = callback; while (running) { if (!server.Server.Poll(1000, SelectMode.SelectRead)) { if (!ctrl.running) { break; } continue; } if (!server.Pending()) { break; } NetHandlerImpl socket = new NetHandlerImpl(server.AcceptSocket(), this); socket.Socket.Blocking = false; socket.OnConnected(); Loop.Run(() => { ctrl.action(socket); }); } lock (listens) { Control ctrlnow; if (listens.TryGetValue(port, out ctrlnow) && ctrlnow == ctrl) { listens.Remove(port); } } server.Stop(); }).Start(); new Thread(delegate() { Thread.CurrentThread.Name = "Network Server"; TcpListener server = new TcpListener(IPAddress.IPv6Any, port); server.Start(); Control ctrl; lock (listensv6) { if (listensv6.TryGetValue(port, out ctrl)) { ctrl.running = true; } else { ctrl = new Control { running = true }; listensv6[port] = ctrl; } } ctrl.action = callback; while (running) { if (!server.Server.Poll(1000, SelectMode.SelectRead)) { if (!ctrl.running) { break; } continue; } if (!server.Pending()) { break; } NetHandlerImpl socket = new NetHandlerImpl(server.AcceptSocket(), this); socket.Socket.Blocking = false; socket.OnConnected(); Loop.Run(() => { ctrl.action(socket); }); } lock (listensv6) { Control ctrlnow; if (listensv6.TryGetValue(port, out ctrlnow) && ctrlnow == ctrl) { listensv6.Remove(port); } } server.Stop(); }).Start(); }
private void ConnectImpl(string host, int port, int timeout, Action <NetHandler, Exception> callback) { if (!running) { throw new ObjectDisposedException(ToString()); } Stopwatch clock = new Stopwatch(); clock.Start(); Dns.BeginGetHostAddresses(host, ar => { clock.Stop(); timeout -= (int)clock.ElapsedMilliseconds; try { IPAddress[] iplist = Dns.EndGetHostAddresses(ar); if (timeout > 0) { AddressFamily family = AddressFamily.InterNetwork; for (int i = 0; i < iplist.Length; ++i) { if (iplist[i].AddressFamily == AddressFamily.InterNetworkV6) { family = AddressFamily.InterNetworkV6; break; } } NetHandlerImpl socket = new NetHandlerImpl(family, this); Timer timer = new Timer(state => { socket.Socket.Close(); }, null, Timeout.Infinite, Timeout.Infinite); socket.Socket.BeginConnect(iplist, port, result => { try { timer.Dispose(); } catch { } Exception exception = null; try { socket.Socket.EndConnect(result); socket.Socket.Blocking = false; socket.OnConnected(); } catch (ObjectDisposedException) { exception = new SocketException((int)SocketError.TimedOut); } catch (Exception e) { exception = e; socket.Socket.Close(); } callback(exception == null ? socket : null, exception); }, null); timer.Change(timeout, Timeout.Infinite); } else { callback(null, new SocketException((int)SocketError.TimedOut)); } } catch (Exception e) { callback(null, e); } }, null); }
private void Init() { if (inited) { return; } inited = true; new Thread(delegate() { Thread.CurrentThread.Name = "Network Task"; List <Socket> reads = new List <Socket>(); List <Socket> writers = new List <Socket>(); List <Socket> errors = new List <Socket>(); Dictionary <Socket, NetHandlerImpl> sockethandlers = new Dictionary <Socket, NetHandlerImpl>(); byte[] bytes = new byte[64 * 1024]; while (valid && IsRunning) { if (newsockets.Count > 0) { lock (newsockets) { sockets.AddRange(newsockets); newsockets.Clear(); } } if (deletesockets.Count > 0) { lock (deletesockets) { for (int i = 0; i < deletesockets.Count; i++) { NetHandlerImpl socket = deletesockets[i]; sockets.Remove(socket); socket.Socket.Close(); if (settings.events.close != null) { Loop.Run(delegate() { if (settings.events.close != null) { settings.events.close(socket); } }); } } deletesockets.Clear(); } } if (sockets.Count == 0) { Thread.Sleep((int)settings.timeout); continue; } for (int i = 0; i < sockets.Count; i++) { NetHandlerImpl socket = sockets[i]; sockethandlers.Add(socket.Socket, socket); reads.Add(socket.Socket); errors.Add(socket.Socket); if (socket.need_send) { writers.Add(socket.Socket); } } Socket.Select(reads, writers, errors, (int)settings.timeout); for (int i = 0; i < writers.Count; i++) { NetHandlerImpl socket = sockethandlers[writers[i]]; ByteBuffer buffer = socket.write_buffer; lock (buffer) { int length = socket.Socket.Send(buffer.array, buffer.offset, buffer.length, SocketFlags.None); buffer.Pop(length); socket.need_send = buffer.length != 0; if (settings.events.write != null) { Loop.Run(delegate() { if (settings.events.write != null) { settings.events.write(socket, length); } }); } } } for (int i = 0; i < reads.Count; i++) { NetHandlerImpl socket = sockethandlers[reads[i]]; try { int total = 0; while (socket.Socket.Available > 0) { int length = socket.Socket.Receive(bytes); if (length == 0) { break; } total += length; socket.OnReceive(bytes, length); } if (total == 0) { lock (deletesockets) { deletesockets.Add(socket); } } else { if (settings.events.read != null) { Loop.Run(delegate() { if (settings.events.read != null) { settings.events.read(socket, total); } }); } } } catch (SocketException e) { if (e.SocketErrorCode == SocketError.ConnectionReset || e.SocketErrorCode == SocketError.ConnectionAborted || e.SocketErrorCode == SocketError.NotConnected || e.SocketErrorCode == SocketError.Shutdown) { lock (deletesockets) { deletesockets.Add(socket); } } else { if (settings.events.exception != null) { Loop.Run(delegate() { if (settings.events.exception != null) { settings.events.exception(socket, e); } }); } } } catch (Exception e) { if (settings.events.exception != null) { Loop.Run(delegate() { if (settings.events.exception != null) { settings.events.exception(socket, e); } }); } } } reads.Clear(); writers.Clear(); errors.Clear(); sockethandlers.Clear(); } }).Start(); }