1 module hunt.io.channel.posix.AbstractDatagramSocket; 2 3 // dfmt off 4 version(Posix): 5 // dfmt on 6 7 import hunt.event.selector.Selector; 8 import hunt.Functions; 9 import hunt.io.channel.AbstractSocketChannel; 10 import hunt.io.channel.Common; 11 import hunt.logging; 12 13 import std.socket; 14 15 /** 16 UDP Socket 17 */ 18 abstract class AbstractDatagramSocket : AbstractSocketChannel { 19 this(Selector loop, AddressFamily family = AddressFamily.INET, int bufferSize = 4096 * 2) { 20 super(loop, ChannelType.UDP); 21 setFlag(ChannelFlag.Read, true); 22 setFlag(ChannelFlag.ETMode, false); 23 24 this.socket = new UdpSocket(family); 25 // _socket.blocking = false; 26 _readBuffer = new UdpDataObject(); 27 _readBuffer.data = new ubyte[bufferSize]; 28 29 if (family == AddressFamily.INET) 30 _bindAddress = new InternetAddress(InternetAddress.PORT_ANY); 31 else if (family == AddressFamily.INET6) 32 _bindAddress = new Internet6Address(Internet6Address.PORT_ANY); 33 else 34 _bindAddress = new UnknownAddress(); 35 } 36 37 final void bind(Address addr) { 38 if (_binded) 39 return; 40 _bindAddress = addr; 41 socket.bind(_bindAddress); 42 _binded = true; 43 } 44 45 final bool isBind() { 46 return _binded; 47 } 48 49 Address bindAddr() { 50 return _bindAddress; 51 } 52 53 protected UdpDataObject _readBuffer; 54 protected bool _binded = false; 55 protected Address _bindAddress; 56 57 protected bool tryRead(scope SimpleActionHandler read) { 58 this._readBuffer.addr = createAddress(this.socket.addressFamily, 0); 59 auto data = this._readBuffer.data; 60 scope (exit) 61 this._readBuffer.data = data; 62 // auto len = this.socket.receiveFrom(this._readBuffer.data, this._readBuffer.addr); 63 64 auto len = this.socket.receiveFrom(this._readBuffer.data, this._readBuffer.addr); 65 if (len > 0) { 66 this._readBuffer.data = this._readBuffer.data[0 .. len]; 67 read(this._readBuffer); 68 } 69 return false; 70 } 71 72 override void onWrite() { 73 version (HUNT_DEBUG) 74 tracef("try to write [fd=%d]", this.handle); 75 } 76 }