public void Close() { //Debug.Log( "CLOSE" ); if (_socket != null) { // Drop multicast group. if (!string.IsNullOrEmpty(_multicastAddress)) { IPAddress multicastIp = IPAddress.Parse(_multicastAddress); try { if (multicastIp.AddressFamily == AddressFamily.InterNetwork) { MulticastOption mcOpt = new MulticastOption(multicastIp); _socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.DropMembership, mcOpt); } else { StringBuilder sb = OscDebug.BuildText(this); sb.Append("IvP6 not supported\n"); Debug.LogWarning(sb.ToString()); } } catch { // Ignore. } } // Close. _socket.Close(); } _socket = null; _isOpen = false; }
/// <summary> /// Tries to evaluate byte count prefix of a blob and evaluate it. /// </summary> // TODO When .Net 4.5 becomes available in Unity: Replace IList<T> with IReadOnlyList<T> since we want to pass Array where number and order of list elements is read-only. public static bool TryReadAndEvaluateByteCountPrefix(IList <byte> data, int index, out int byteCountPrefixValue) { FourByteOscData byteCountPrefix; if (!FourByteOscData.TryReadFrom(data, ref index, out byteCountPrefix)) { // Not enough space for byte count prefix in data array. byteCountPrefixValue = 0; StringBuilder sb = OscDebug.BuildText(); sb.Append("Blob is missing byte count prefix.\n"); Debug.LogWarning(sb.ToString()); return(false); } int multipleOfFourByteCount = ((byteCountPrefix.intValue + 3) / 4) * 4; // Multiple of four bytes. if (index + multipleOfFourByteCount > data.Count) { // Not enough space for blob in data array. byteCountPrefixValue = 0; StringBuilder sb = OscDebug.BuildText(); sb.Append("Blob data is incomplete.\n"); Debug.LogWarning(sb.ToString()); return(false); } byteCountPrefixValue = byteCountPrefix.intValue; return(true); }
void ReceiveComplete(IAsyncResult asyncResult) { if (_socket == null) { return; } try { // Get the data and copy it to another buffer for exposure. int byteCount = _socket.EndReceiveFrom(asyncResult, ref _tempRemoteEndPoint); Buffer.BlockCopy(_buffer, 0, _exposedBuffer, 0, byteCount); // Immediately start receving again. if (_isOpen) { BeginRecieve(); } // Invoke callback with the exposed buffer. if (byteCount > 0) { _onDatagramReceivedAsyncCallback(_exposedBuffer, byteCount); } } catch (Exception e) { if (e is ObjectDisposedException) { // Ignore. } else { StringBuilder sb = OscDebug.BuildText(this); sb.Append("Error occurred while receiving message.\n"); sb.Append(e); Debug.LogWarning(sb.ToString()); } } }
public bool Open(int port, string multicastAddress = "") { //Debug.Log( "OPEN " + Application.isPlaying ); if (_isOpen) { Close(); } // "Do not attempt to reuse the Socket after closing". // https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.socket.shutdown?view=netframework-4.7.2 _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); // Ensure that we can have multiple OscIn objects listening to the same port. Must be set before bind. // Note that only one OscIn object will receive the packet anyway: http://stackoverflow.com/questions/22810511/bind-multiple-listener-to-the-same-port _socket.ExclusiveAddressUse = false; _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); _port = port; _multicastAddress = multicastAddress; try { // "Before calling BeginReceiveFrom, you must explicitly bind the Socket to a local endpoint using the Bind method," // https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.socket.beginreceivefrom?view=netframework-4.7.2 IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, _port); _socket.Bind(localEndPoint); // Join multicast group if in multicast mode. if (!string.IsNullOrEmpty(_multicastAddress)) { IPAddress multicastIp = IPAddress.Parse(_multicastAddress); if (multicastIp.AddressFamily == AddressFamily.InterNetwork) { MulticastOption mcOpt = new MulticastOption(multicastIp); _socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, mcOpt); } else { StringBuilder sb = OscDebug.BuildText(this); sb.Append("IvP6 not supported\n"); Debug.LogWarning(sb.ToString()); return(false); } _socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, OscConst.timeToLive); } // Let's begin! BeginRecieve(); } catch (Exception e) { // Socket error reference: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx Debug.Log(e); if (e is SocketException && (e as SocketException).ErrorCode == 10048) // "Address already in use" { StringBuilder sb = OscDebug.BuildText(this); sb.Append("Could not open port "); sb.Append(_port); sb.Append(" because another application is listening on it.\n"); Debug.LogWarning(sb.ToString()); } else if (e is SocketException && !string.IsNullOrEmpty(multicastAddress)) { StringBuilder sb = OscDebug.BuildText(this); sb.Append("Could not subscribe to multicast group. Perhaps you are offline, or your router does not support multicast."); sb.Append((e as SocketException).ErrorCode); sb.Append(": "); sb.Append(e.ToString()); Debug.LogWarning(sb.ToString()); } else if (e.Data is ArgumentOutOfRangeException) { StringBuilder sb = OscDebug.BuildText(this); sb.Append("Could not open port "); sb.Append(_port); sb.Append(". Invalid Port Number.\n"); sb.Append(e); Debug.LogWarning(sb.ToString()); } else { //Debug.Log( e ); } Close(); return(false); } _isOpen = true; return(true); }
public bool TrySendBuffer(byte[] buffer, int byteCount) { if (_endPoint == null) { return(false); } try { //Debug.Log( $"Actually sending { string.Join( ",", _cache ) }" ); //Debug.Log( "Sending bytes: " + byteCount + ". Frame: " + Time.frameCount + "\n"); //Debug.Log( "Sending to " + _endPoint ); // Send!! _socket.SendTo(buffer, byteCount, SocketFlags.None, _endPoint); // Socket error reference: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx } catch (SocketException ex) { if (ex.ErrorCode == 10051) // "Network is unreachable" // Ignore. We get this when broadcasting while having no access to a network. { } else if (ex.ErrorCode == 10065) // "No route to host" // Ignore. We get this sometimes when unicasting. { } else if (ex.ErrorCode == 10049) // "The requested address is not valid in this context" // Ignore. We get this when we broadcast and have no access to the local network. For example if we are using a VPN. { } else if (ex.ErrorCode == 10061) // "Connection refused" // Ignore. { } else if (ex.ErrorCode == 10064) // "Host is down" // Ignore. We get this when the remote target is not found. { } else if (ex.ErrorCode == 10040) // "Message too long" { if (OscGlobals.logWarnings) { Debug.LogWarning( OscDebug.BuildText(this).Append("Failed to send message. Packet size at ") .AppendGarbageFree(byteCount).Append(" bytes exceeds udp buffer size at ") .AppendGarbageFree(_socket.SendBufferSize) .Append(" Try increasing the buffer size.\n").Append(ex) ); } } else { if (OscGlobals.logWarnings) { Debug.LogWarning( OscDebug.BuildText(this).Append("Failed to send message to ") .Append(_endPoint.Address).Append(" on port ").AppendGarbageFree(_endPoint.Port) .Append(".\n").Append(ex) ); } } return(false); } catch (Exception ex) { if (OscGlobals.logWarnings) { Debug.LogWarning( OscDebug.BuildText(this).Append("Failed to send message to ") .Append(_endPoint.Address).Append(" on port ").AppendGarbageFree(_endPoint.Port) .Append(".\n").Append(ex) ); } return(false); } return(true); }