1 /* 2 * Geario - A cross-platform abstraction library with asynchronous I/O. 3 * 4 * Copyright (C) 2021-2022 Kerisy.com 5 * 6 * Website: https://www.kerisy.com 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module geario.net.UdpSocket; 13 14 import geario.event; 15 import geario.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 _loop.Register(this); 74 _isRegistered = true; 75 version (HAVE_IOCP) 76 DoRead(); 77 } 78 79 protected override void OnRead() { 80 bool canRead = true; 81 while (canRead && _isRegistered) { 82 version (GEAR_IO_DEBUG) 83 log.trace("reading data..."); 84 canRead = tryRead((Object obj) { 85 collectException(() { 86 UdpDataObject data = cast(UdpDataObject) obj; 87 if (data !is null) { 88 _receivedHandler(data.data, data.addr); 89 } 90 }()); 91 }); 92 93 if (this.IsError) { 94 canRead = false; 95 this.Close(); 96 log.error("UDP socket Error: ", this.ErrorMessage); 97 } 98 } 99 } 100 101 }