1 /* 2 * Hunt - A refined core library for D programming language. 3 * 4 * Copyright (C) 2018-2019 HuntLabs 5 * 6 * Website: https://www.huntlabs.net/ 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.io.UdpSocket; 13 14 import hunt.event; 15 import hunt.logging; 16 17 import std.socket; 18 import std.exception; 19 20 /** 21 */ 22 class UdpSocket : AbstractDatagramSocket { 23 24 private UdpDataHandler _receivedHandler; 25 26 this(EventLoop loop, AddressFamily amily = AddressFamily.INET) { 27 super(loop, amily); 28 } 29 30 UdpSocket enableBroadcast(bool flag) { 31 this.socket.setOption(SocketOptionLevel.SOCKET, SocketOption.BROADCAST, flag); 32 return this; 33 } 34 35 UdpSocket onReceived(UdpDataHandler handler) { 36 _receivedHandler = handler; 37 return this; 38 } 39 40 ptrdiff_t sendTo(const(void)[] buf, Address to) { 41 return this.socket.sendTo(buf, to); 42 } 43 44 ptrdiff_t sendTo(const(void)[] buf) { 45 return this.socket.sendTo(buf); 46 } 47 48 ptrdiff_t sendTo(const(void)[] buf, SocketFlags flags, Address to) { 49 return this.socket.sendTo(buf, flags, to); 50 } 51 52 UdpSocket bind(string ip, ushort port) { 53 super.bind(parseAddress(ip, port)); 54 return this; 55 } 56 57 UdpSocket bind(Address address) { 58 super.bind(address); 59 return this; 60 } 61 62 UdpSocket connect(Address addr) { 63 this.socket.connect(addr); 64 return this; 65 } 66 67 override void start() { 68 if (!_binded) { 69 socket.bind(_bindAddress); 70 _binded = true; 71 } 72 73 _inLoop.register(this); 74 _isRegistered = true; 75 version (HAVE_IOCP) 76 doRead(); 77 } 78 79 protected override void onRead() nothrow { 80 catchAndLogException(() { 81 bool canRead = true; 82 while (canRead && _isRegistered) { 83 version (HUNT_IO_DEBUG) 84 trace("reading data..."); 85 canRead = tryRead((Object obj) nothrow{ 86 collectException(() { 87 UdpDataObject data = cast(UdpDataObject) obj; 88 if (data !is null) { 89 _receivedHandler(data.data, data.addr); 90 } 91 }()); 92 }); 93 94 if (this.isError) { 95 canRead = false; 96 this.close(); 97 error("UDP socket error: ", this.errorMessage); 98 } 99 } 100 }()); 101 } 102 103 }