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;
        }
Exemple #2
0
        /// <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);
        }
Exemple #5
0
        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);
        }