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 }