1 module geario.net.channel.iocp.AbstractListener; 2 3 // dfmt off 4 version (HAVE_IOCP) : 5 // dfmt on 6 7 import geario.event.selector.Selector; 8 import geario.net.channel.AbstractSocketChannel; 9 import geario.net.channel.Types; 10 import geario.net.channel.iocp.Common; 11 import geario.logging; 12 import geario.Functions; 13 14 import core.sys.windows.windows; 15 import core.sys.windows.winsock2; 16 import core.sys.windows.mswsock; 17 18 import std.socket; 19 20 21 22 /** 23 TCP Server 24 */ 25 abstract class AbstractListener : AbstractSocketChannel { 26 this(Selector loop, AddressFamily family = AddressFamily.INET, size_t bufferSize = 4 * 1024) { 27 super(loop, ChannelType.Accept); 28 setFlag(ChannelFlag.Read, true); 29 _buffer = new ubyte[bufferSize]; 30 this.socket = new TcpSocket(family); 31 32 loadWinsockExtension(this.handle); 33 } 34 35 mixin CheckIocpError; 36 37 protected void DoAccept() { 38 _iocp.channel = this; 39 _iocp.operation = IocpOperation.accept; 40 _clientSocket = new Socket(this.LocalAddress.addressFamily, 41 SocketType.STREAM, ProtocolType.TCP); 42 DWORD dwBytesReceived = 0; 43 44 version (GEAR_DEBUG) { 45 log.trace("client socket: acceptor=%s inner socket=%s", this.handle, 46 _clientSocket.handle()); 47 // Info("AcceptEx@", AcceptEx); 48 } 49 uint sockaddrSize = cast(uint) sockaddr_storage.sizeof; 50 // https://docs.microsoft.com/en-us/windows/desktop/api/mswsock/nf-mswsock-acceptex 51 BOOL ret = AcceptEx(this.handle, cast(SOCKET) _clientSocket.handle, _buffer.ptr, 52 0, sockaddrSize + 16, sockaddrSize + 16, &dwBytesReceived, &_iocp.overlapped); 53 version (GEAR_DEBUG) 54 Trace("AcceptEx return: ", ret); 55 checkErro(ret, FALSE); 56 } 57 58 protected bool OnAccept(scope AcceptHandler handler) { 59 version (GEAR_DEBUG) 60 Trace("a new connection coming..."); 61 this.ClearError(); 62 SOCKET slisten = cast(SOCKET) this.handle; 63 SOCKET slink = cast(SOCKET) this._clientSocket.handle; 64 // void[] value = (&slisten)[0..1]; 65 // setsockopt(slink, SocketOptionLevel.SOCKET, 0x700B, value.ptr, 66 // cast(uint) value.length); 67 version (GEAR_DEBUG) 68 log.trace("slisten=%s, slink=%s", slisten, slink); 69 setsockopt(slink, SocketOptionLevel.SOCKET, 0x700B, cast(void*)&slisten, slisten.sizeof); 70 if (handler !is null) 71 handler(this._clientSocket); 72 73 version (GEAR_DEBUG) 74 Trace("accepting next connection..."); 75 if (this.IsRegistered) 76 this.DoAccept(); 77 return true; 78 } 79 80 override void OnClose() { 81 82 // version (GEAR_DEBUG) 83 // log.trace("_isWritting=%s", _isWritting); 84 // _isWritting = false; 85 // assert(false, ""); 86 // TODO: created by Administrator @ 2018-3-27 15:51:52 87 } 88 89 private IocpContext _iocp; 90 private WSABUF _dataWriteBuffer; 91 private ubyte[] _buffer; 92 private Socket _clientSocket; 93 }