1 module geario.net.channel.posix.AbstractDatagramSocket;
2 
3 // dfmt off
4 version(Posix):
5 // dfmt on
6 
7 import geario.event.selector.Selector;
8 import geario.Functions;
9 import geario.net.channel.AbstractSocketChannel;
10 import geario.net.channel.Types;
11 import geario.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 (GEAR_DEBUG)
74             log.trace("try to write [fd=%d]", this.handle);
75     }
76 }