コード例 #1
0
ファイル: UdpTransceiver.cs プロジェクト: yssource/ice
        StartWrite(IList <ArraySegment <byte> > buffer, int offset, AsyncCallback callback, object state, out bool completed)
        {
            Debug.Assert(_fd != null);
            Debug.Assert(_writeEventArgs != null);
            Debug.Assert(offset == 0);
            bool completedSynchronously;

            if (!_incoming && _state < StateConnected)
            {
                Debug.Assert(_addr != null);
                completed = false;
                if (_sourceAddr != null)
                {
                    _fd.Bind(_sourceAddr);
                }
                _writeEventArgs.UserToken = state;
                return(!_fd.ConnectAsync(_writeEventArgs));
            }

            // The caller is supposed to check the send size before by calling checkSendSize
            Debug.Assert(Math.Min(MaxPacketSize, _sndSize - UdpOverhead) >= buffer.GetByteCount());

            try
            {
                _writeCallback = callback;

                if (_state == StateConnected)
                {
                    _writeEventArgs.UserToken  = state;
                    _writeEventArgs.BufferList = buffer;
                    completedSynchronously     = !_fd.SendAsync(_writeEventArgs);
                }
                else
                {
                    if (_peerAddr == null)
                    {
                        throw new Ice.SocketException();
                    }
                    _writeEventArgs.RemoteEndPoint = _peerAddr;
                    _writeEventArgs.UserToken      = state;
                    ArraySegment <byte> data = buffer.GetSegment(0, buffer.GetByteCount());
                    _writeEventArgs.SetBuffer(data.Array, 0, data.Count);

                    completedSynchronously = !_fd.SendToAsync(_writeEventArgs);
                }
            }
            catch (System.Net.Sockets.SocketException ex)
            {
                if (Network.ConnectionLost(ex))
                {
                    throw new Ice.ConnectionLostException(ex);
                }
                else
                {
                    throw new Ice.SocketException(ex);
                }
            }
            completed = true;
            return(completedSynchronously);
        }
コード例 #2
0
ファイル: StreamSocket.cs プロジェクト: sgrzegorz/ice
        /// <summary>Finish an asynchronous write operation, the offset is increase with the
        /// number of bytes actually wrote to the socket.</summary>
        /// <param name="buffer">The buffer of data to write to the socket.</param>
        /// <param name="offset">The offset at what the write operation starts, the offset is increase
        /// with the number of bytes successfully wrote to the socket.</param>
        public void FinishWrite(IList <ArraySegment <byte> > buffer, ref int offset)
        {
            if (_writeEventArgs.BufferList != null)
            {
                _writeEventArgs.BufferList.Clear();
                _writeEventArgs.BufferList = null;
            }

            if (_fd == null) // Transceiver was closed
            {
                int remaining = buffer.GetByteCount() - offset;
                if (remaining <= _maxSendPacketSize)
                {
                    offset += remaining; // Assume all the data was sent for at-most-once semantics.
                }
                return;
            }

            Debug.Assert(_fd != null && _writeEventArgs != null);

            if (_state < StateConnected && _state != StateProxyWrite)
            {
                return;
            }

            try
            {
                if (_writeEventArgs.SocketError != SocketError.Success)
                {
                    throw new SocketException((int)_writeEventArgs.SocketError);
                }
                int ret = _writeEventArgs.BytesTransferred;
                if (ret == 0)
                {
                    throw new ConnectionLostException();
                }
                Debug.Assert(ret > 0);
                if (_state == StateProxyWrite)
                {
                    Debug.Assert(_proxy != null);
                    _state = ToState(_proxy.EndWrite(buffer, ret));
                }
                offset += ret;
            }
            catch (SocketException ex)
            {
                if (Network.ConnectionLost(ex))
                {
                    throw new ConnectionLostException(ex);
                }

                throw new TransportException(ex);
            }
            catch (ObjectDisposedException ex)
            {
                throw new ConnectionLostException(ex);
            }
        }
コード例 #3
0
ファイル: StreamSocket.cs プロジェクト: menghuan341/ice
        private int Write(ByteBuffer buf)
        {
            Debug.Assert(_fd != null);
            if (AssemblyUtil.IsMono)
            {
                //
                // Mono on Android and iOS don't support the use of synchronous socket
                // operations on a non-blocking socket. Returning 0 here forces the caller to schedule
                // an asynchronous operation.
                //
                return(0);
            }
            int packetSize = buf.Remaining();

            if (AssemblyUtil.IsWindows)
            {
                //
                // On Windows, limiting the buffer size is important to prevent
                // poor throughput performances when transfering large amount of
                // data. See Microsoft KB article KB823764.
                //
                if (_maxSendPacketSize > 0 && packetSize > _maxSendPacketSize / 2)
                {
                    packetSize = _maxSendPacketSize / 2;
                }
            }

            int sent = 0;

            while (buf.HasRemaining())
            {
                try
                {
                    int ret = _fd.Send(buf.RawBytes(), buf.Position(), packetSize, SocketFlags.None);
                    Debug.Assert(ret > 0);

                    sent += ret;
                    buf.Position(buf.Position() + ret);
                    if (packetSize > buf.Remaining())
                    {
                        packetSize = buf.Remaining();
                    }
                }
                catch (SocketException ex)
                {
                    if (Network.WouldBlock(ex))
                    {
                        return(sent);
                    }
                    else if (Network.ConnectionLost(ex))
                    {
                        throw new Ice.ConnectionLostException(ex);
                    }
                    throw new Ice.SocketException(ex);
                }
            }
            return(sent);
        }
コード例 #4
0
        public void FinishWrite(Buffer buf)
        {
            Debug.Assert(_writeEventArgs != null);
            if (_fd == null)
            {
                buf.B.Position(buf.Size()); // Assume all the data was sent for at-most-once semantics.
                _writeEventArgs = null;
                return;
            }

            if (!_incoming && _state < StateConnected)
            {
                if (_writeEventArgs.SocketError != SocketError.Success)
                {
                    var ex = new SocketException((int)_writeEventArgs.SocketError);
                    if (Network.ConnectionRefused(ex))
                    {
                        throw new Ice.ConnectionRefusedException(ex);
                    }
                    else
                    {
                        throw new Ice.ConnectFailedException(ex);
                    }
                }
                return;
            }

            int ret;

            try
            {
                if (_writeEventArgs.SocketError != SocketError.Success)
                {
                    throw new SocketException((int)_writeEventArgs.SocketError);
                }
                ret = _writeEventArgs.BytesTransferred;
            }
            catch (SocketException ex)
            {
                if (Network.ConnectionLost(ex))
                {
                    throw new Ice.ConnectionLostException(ex);
                }
                else
                {
                    throw new Ice.SocketException(ex);
                }
            }

            if (ret == 0)
            {
                throw new Ice.ConnectionLostException();
            }

            Debug.Assert(ret > 0);
            Debug.Assert(ret == buf.B.Limit());
            buf.B.Position(buf.B.Position() + ret);
        }
コード例 #5
0
ファイル: StreamSocket.cs プロジェクト: sgrzegorz/ice
        private int WriteData(IList <ArraySegment <byte> > buffer, int offset, int count)
        {
            Debug.Assert(_fd != null);
            if (AssemblyUtil.IsMono)
            {
                //
                // Mono on Android and iOS don't support the use of synchronous socket
                // operations on a non-blocking socket. Returning 0 here forces the caller to schedule
                // an asynchronous operation.
                //
                return(0);
            }

            int packetSize = _maxSendPacketSize;

            if (AssemblyUtil.IsWindows)
            {
                //
                // On Windows, limiting the buffer size is important to prevent
                // poor throughput performances when transferring large amount of
                // data. See Microsoft KB article KB823764.
                //
                if (_maxSendPacketSize > 0 && packetSize > _maxSendPacketSize / 2)
                {
                    packetSize = _maxSendPacketSize / 2;
                }
            }

            int remaining = count - offset;
            int sent      = 0;

            while (remaining - sent > 0)
            {
                try
                {
                    buffer.FillSegments(offset + sent, _sendSegments, Math.Min(remaining - sent, packetSize));
                    int ret = _fd.Send(_sendSegments, SocketFlags.None);
                    _sendSegments.Clear();
                    Debug.Assert(ret > 0);
                    sent += ret;
                }
                catch (SocketException ex)
                {
                    if (Network.WouldBlock(ex))
                    {
                        return(sent);
                    }
                    else if (Network.ConnectionLost(ex))
                    {
                        throw new ConnectionLostException(ex);
                    }
                    throw new TransportException(ex);
                }
            }
            return(sent);
        }
コード例 #6
0
        /// <summary>Starts an asynchronous write operation of the buffer data to the socket
        /// starting at the given offset, completed is set to true if the write operation
        /// account for the remaining of the buffer data or false otheriwse, returns whenever
        /// the asynchronous operation completed synchronously or not.</summary>
        /// <param name="buffer">The data to write to the socket as a list of byte array segments.</param>
        /// <param name="offset">The zero based byte offset into the buffer at what start writing.</param>
        /// <param name="callback">The asyncrhonous completion callback.</param>
        /// <param name="state">A state object that is asocciated with the asynchronous operation.</param>
        /// <param name="completed">True if the write operation accounts for the buffer remaining data, from
        /// offset to the end of the buffer.</param>
        /// <returns>True if the asynchronous operation compled synchronously otherwise false.</returns>
        public bool StartWrite(IList <ArraySegment <byte> > buffer, int offset, AsyncCallback callback, object state,
                               out bool completed)
        {
            Debug.Assert(_fd != null && _writeEventArgs != null);
            if (_state == StateConnectPending)
            {
                completed      = false;
                _writeCallback = callback;
                try
                {
                    EndPoint addr;
                    if (_proxy != null)
                    {
                        addr = _proxy.GetAddress();
                    }
                    else
                    {
                        Debug.Assert(_addr != null);
                        addr = _addr;
                    }
                    _writeEventArgs.RemoteEndPoint = addr;
                    _writeEventArgs.UserToken      = state;
                    return(!_fd.ConnectAsync(_writeEventArgs));
                }
                catch (System.Exception ex)
                {
                    throw new Ice.TransportException(ex);
                }
            }

            try
            {
                int count     = buffer.GetByteCount();
                int remaining = count - offset;
                buffer.FillSegments(offset, _sendSegments, Math.Min(remaining, _maxSendPacketSize));
                _writeCallback             = callback;
                _writeEventArgs.UserToken  = state;
                _writeEventArgs.BufferList = _sendSegments;
                bool completedSynchronously = !_fd.SendAsync(_writeEventArgs);
                completed = _maxSendPacketSize >= remaining;
                return(completedSynchronously);
            }
            catch (System.Net.Sockets.SocketException ex)
            {
                if (Network.ConnectionLost(ex))
                {
                    throw new ConnectionLostException(ex);
                }
                throw new Ice.TransportException(ex);
            }
            catch (ObjectDisposedException ex)
            {
                throw new ConnectionLostException(ex);
            }
        }
コード例 #7
0
ファイル: StreamSocket.cs プロジェクト: menghuan341/ice
        public void FinishWrite(Buffer buf)
        {
            if (_fd == null) // Transceiver was closed
            {
                if (buf.Size() - buf.B.Position() < _maxSendPacketSize)
                {
                    buf.B.Position(buf.B.Limit()); // Assume all the data was sent for at-most-once semantics.
                }
                return;
            }

            Debug.Assert(_fd != null && _writeEventArgs != null);

            if (_state < StateConnected && _state != StateProxyWrite)
            {
                return;
            }

            try
            {
                if (_writeEventArgs.SocketError != SocketError.Success)
                {
                    throw new SocketException((int)_writeEventArgs.SocketError);
                }
                int ret = _writeEventArgs.BytesTransferred;
                _writeEventArgs.SetBuffer(null, 0, 0);
                if (ret == 0)
                {
                    throw new Ice.ConnectionLostException();
                }

                Debug.Assert(ret > 0);
                buf.B.Position(buf.B.Position() + ret);

                if (_state == StateProxyWrite)
                {
                    Debug.Assert(_proxy != null);
                    _state = ToState(_proxy.EndWrite(buf));
                }
            }
            catch (SocketException ex)
            {
                if (Network.ConnectionLost(ex))
                {
                    throw new Ice.ConnectionLostException(ex);
                }

                throw new Ice.SocketException(ex);
            }
            catch (ObjectDisposedException ex)
            {
                throw new Ice.ConnectionLostException(ex);
            }
        }
コード例 #8
0
ファイル: StreamSocket.cs プロジェクト: menghuan341/ice
        public bool StartWrite(Buffer buf, AsyncCallback callback, object state, out bool completed)
        {
            Debug.Assert(_fd != null && _writeEventArgs != null);
            if (_state == StateConnectPending)
            {
                completed      = false;
                _writeCallback = callback;
                try
                {
                    EndPoint addr;
                    if (_proxy != null)
                    {
                        addr = _proxy.GetAddress();
                    }
                    else
                    {
                        Debug.Assert(_addr != null);
                        addr = _addr;
                    }
                    _writeEventArgs.RemoteEndPoint = addr;
                    _writeEventArgs.UserToken      = state;
                    return(!_fd.ConnectAsync(_writeEventArgs));
                }
                catch (Exception ex)
                {
                    throw new Ice.SocketException(ex);
                }
            }

            int packetSize = GetSendPacketSize(buf.B.Remaining());

            try
            {
                _writeCallback            = callback;
                _writeEventArgs.UserToken = state;
                _writeEventArgs.SetBuffer(buf.B.RawBytes(), buf.B.Position(), packetSize);
                bool completedSynchronously = !_fd.SendAsync(_writeEventArgs);
                completed = packetSize == buf.B.Remaining();
                return(completedSynchronously);
            }
            catch (SocketException ex)
            {
                if (Network.ConnectionLost(ex))
                {
                    throw new Ice.ConnectionLostException(ex);
                }
                throw new Ice.SocketException(ex);
            }
            catch (ObjectDisposedException ex)
            {
                throw new Ice.ConnectionLostException(ex);
            }
        }
コード例 #9
0
        public bool StartRead(Buffer buf, AsyncCallback callback, object state)
        {
            Debug.Assert(_fd != null);
            Debug.Assert(buf.B.Position() == 0);

            int packetSize = Math.Min(MaxPacketSize, _rcvSize - UdpOverhead);

            buf.Resize(packetSize, true);
            buf.B.Position(0);

            try
            {
                // TODO: Workaround for https://github.com/dotnet/corefx/issues/31182
                if (_state == StateConnected ||
                    (AssemblyUtil.IsMacOS && _fd.AddressFamily == AddressFamily.InterNetworkV6 && _fd.DualMode))
                {
                    _readCallback            = callback;
                    _readEventArgs.UserToken = state;
                    _readEventArgs.SetBuffer(buf.B.RawBytes(), buf.B.Position(), packetSize);
                    return(!_fd.ReceiveAsync(_readEventArgs));
                }
                else
                {
                    Debug.Assert(_incoming);
                    _readCallback            = callback;
                    _readEventArgs.UserToken = state;
                    _readEventArgs.SetBuffer(buf.B.RawBytes(), 0, buf.B.Limit());
                    return(!_fd.ReceiveFromAsync(_readEventArgs));
                }
            }
            catch (SocketException ex)
            {
                if (Network.RecvTruncated(ex))
                {
                    // Nothing todo
                    return(true);
                }
                else
                {
                    if (Network.ConnectionLost(ex))
                    {
                        throw new Ice.ConnectionLostException(ex);
                    }
                    else
                    {
                        throw new Ice.SocketException(ex);
                    }
                }
            }
        }
コード例 #10
0
ファイル: StreamSocket.cs プロジェクト: sgrzegorz/ice
        private int ReadData(ArraySegment <byte> buffer, int offset)
        {
            Debug.Assert(_fd != null);
            if (AssemblyUtil.IsMono)
            {
                //
                // Mono on Android and iOS don't support the use of synchronous socket
                // operations on a non-blocking socket. Returning 0 here forces the caller to schedule
                // an asynchronous operation.
                //
                return(0);
            }

            int bytesTransferred = 0;
            int bufferOffset     = buffer.Offset + offset;

            while (buffer.Count - (offset + bytesTransferred) > 0)
            {
                try
                {
                    int ret = _fd.Receive(buffer.Array, bufferOffset + bytesTransferred,
                                          GetRecvPacketSize(buffer.Count - (offset + bytesTransferred)),
                                          SocketFlags.None);
                    if (ret == 0)
                    {
                        throw new ConnectionLostException();
                    }
                    bytesTransferred += ret;
                }
                catch (SocketException ex)
                {
                    if (Network.WouldBlock(ex))
                    {
                        return(bytesTransferred);
                    }
                    else if (Network.Interrupted(ex))
                    {
                        continue;
                    }
                    else if (Network.ConnectionLost(ex))
                    {
                        throw new ConnectionLostException(ex);
                    }

                    throw new TransportException(ex);
                }
            }
            return(bytesTransferred);
        }
コード例 #11
0
ファイル: UdpTransceiver.cs プロジェクト: yssource/ice
        public bool StartRead(ref ArraySegment <byte> buffer, ref int offset, AsyncCallback callback, object state)
        {
            Debug.Assert(_fd != null);
            Debug.Assert(offset == 0, $"offset: {offset}\n{Environment.StackTrace}");

            int packetSize = Math.Min(MaxPacketSize, _rcvSize - UdpOverhead);

            Debug.Assert(buffer.Count == 0);
            buffer = new byte[packetSize];

            try
            {
                // TODO: Workaround for https://github.com/dotnet/corefx/issues/31182
                _readCallback            = callback;
                _readEventArgs.UserToken = state;
                _readEventArgs.SetBuffer(buffer.Array, 0, packetSize);
                if (_state == StateConnected ||
                    (AssemblyUtil.IsMacOS && _fd.AddressFamily == AddressFamily.InterNetworkV6 && _fd.DualMode))
                {
                    return(!_fd.ReceiveAsync(_readEventArgs));
                }
                else
                {
                    Debug.Assert(_incoming);

                    return(!_fd.ReceiveFromAsync(_readEventArgs));
                }
            }
            catch (System.Net.Sockets.SocketException ex)
            {
                if (Network.RecvTruncated(ex))
                {
                    // Nothing todo
                    return(true);
                }
                else
                {
                    if (Network.ConnectionLost(ex))
                    {
                        throw new Ice.ConnectionLostException(ex);
                    }
                    else
                    {
                        throw new Ice.SocketException(ex);
                    }
                }
            }
        }
コード例 #12
0
ファイル: StreamSocket.cs プロジェクト: menghuan341/ice
        private int Read(ByteBuffer buf)
        {
            Debug.Assert(_fd != null);
            if (AssemblyUtil.IsMono)
            {
                //
                // Mono on Android and iOS don't support the use of synchronous socket
                // operations on a non-blocking socket. Returning 0 here forces the caller to schedule
                // an asynchronous operation.
                //
                return(0);
            }
            int read = 0;

            while (buf.HasRemaining())
            {
                try
                {
                    int ret = _fd.Receive(buf.RawBytes(), buf.Position(), buf.Remaining(), SocketFlags.None);
                    if (ret == 0)
                    {
                        throw new Ice.ConnectionLostException();
                    }
                    read += ret;
                    buf.Position(buf.Position() + ret);
                }
                catch (SocketException ex)
                {
                    if (Network.WouldBlock(ex))
                    {
                        return(read);
                    }
                    else if (Network.Interrupted(ex))
                    {
                        continue;
                    }
                    else if (Network.ConnectionLost(ex))
                    {
                        throw new Ice.ConnectionLostException(ex);
                    }

                    throw new Ice.SocketException(ex);
                }
            }
            return(read);
        }
コード例 #13
0
ファイル: StreamSocket.cs プロジェクト: menghuan341/ice
        public void FinishRead(Buffer buf)
        {
            if (_fd == null) // Transceiver was closed
            {
                return;
            }

            Debug.Assert(_fd != null && _readEventArgs != null);
            try
            {
                if (_readEventArgs.SocketError != SocketError.Success)
                {
                    throw new SocketException((int)_readEventArgs.SocketError);
                }
                int ret = _readEventArgs.BytesTransferred;
                _readEventArgs.SetBuffer(null, 0, 0);

                if (ret == 0)
                {
                    throw new Ice.ConnectionLostException();
                }

                Debug.Assert(ret > 0);
                buf.B.Position(buf.B.Position() + ret);

                if (_state == StateProxyRead)
                {
                    Debug.Assert(_proxy != null);
                    _state = ToState(_proxy.EndRead(buf));
                }
            }
            catch (SocketException ex)
            {
                if (Network.ConnectionLost(ex))
                {
                    throw new Ice.ConnectionLostException(ex);
                }
                throw new Ice.SocketException(ex);
            }
            catch (ObjectDisposedException ex)
            {
                throw new Ice.ConnectionLostException(ex);
            }
        }
コード例 #14
0
        public void FinishRead(ref ArraySegment <byte> buffer, ref int offset)
        {
            if (_fd == null) // Transceiver was closed
            {
                return;
            }

            Debug.Assert(_fd != null && _readEventArgs != null);
            try
            {
                if (_readEventArgs.SocketError != SocketError.Success)
                {
                    throw new System.Net.Sockets.SocketException((int)_readEventArgs.SocketError);
                }
                int ret = _readEventArgs.BytesTransferred;
                _readEventArgs.SetBuffer(null, 0, 0);

                if (ret == 0)
                {
                    throw new ConnectionLostException();
                }

                Debug.Assert(ret > 0);
                offset += ret;
                if (_state == StateProxyRead)
                {
                    Debug.Assert(_proxy != null);
                    _state = ToState(_proxy.EndRead(ref buffer, offset));
                }
            }
            catch (System.Net.Sockets.SocketException ex)
            {
                if (Network.ConnectionLost(ex))
                {
                    throw new Ice.ConnectionLostException(ex);
                }
                throw new Ice.TransportException(ex);
            }
            catch (ObjectDisposedException ex)
            {
                throw new ConnectionLostException(ex);
            }
        }
コード例 #15
0
ファイル: StreamSocket.cs プロジェクト: sgrzegorz/ice
        public bool StartRead(ArraySegment <byte> buffer, int offset, AsyncCallback callback, object state)
        {
            Debug.Assert(_fd != null && _readEventArgs != null);
            int packetSize = GetRecvPacketSize(buffer.Count - offset);

            try
            {
                _readCallback            = callback;
                _readEventArgs.UserToken = state;
                _readEventArgs.SetBuffer(buffer.Array, buffer.Offset + offset, packetSize);
                return(!_fd.ReceiveAsync(_readEventArgs));
            }
            catch (SocketException ex)
            {
                if (Network.ConnectionLost(ex))
                {
                    throw new ConnectionLostException(ex);
                }
                throw new TransportException(ex);
            }
        }
コード例 #16
0
ファイル: StreamSocket.cs プロジェクト: menghuan341/ice
        public bool StartRead(Buffer buf, AsyncCallback callback, object state)
        {
            Debug.Assert(_fd != null && _readEventArgs != null);

            int packetSize = GetRecvPacketSize(buf.B.Remaining());

            try
            {
                _readCallback            = callback;
                _readEventArgs.UserToken = state;
                _readEventArgs.SetBuffer(buf.B.RawBytes(), buf.B.Position(), packetSize);
                return(!_fd.ReceiveAsync(_readEventArgs));
            }
            catch (SocketException ex)
            {
                if (Network.ConnectionLost(ex))
                {
                    throw new Ice.ConnectionLostException(ex);
                }
                throw new Ice.SocketException(ex);
            }
        }
コード例 #17
0
ファイル: UdpTransceiver.cs プロジェクト: yssource/ice
        public void FinishWrite(IList <ArraySegment <byte> > buffer, ref int offset)
        {
            Debug.Assert(_writeEventArgs != null);
            Debug.Assert(offset == 0);
            if (_fd == null)
            {
                int count = buffer.GetByteCount(); // Assume all the data was sent for at-most-once semantics.
                _writeEventArgs = null;
                offset          = count;
                return;
            }

            if (!_incoming && _state < StateConnected)
            {
                if (_writeEventArgs.SocketError != SocketError.Success)
                {
                    var ex = new System.Net.Sockets.SocketException((int)_writeEventArgs.SocketError);
                    if (Network.ConnectionRefused(ex))
                    {
                        throw new ConnectionRefusedException(ex);
                    }
                    else
                    {
                        throw new ConnectFailedException(ex);
                    }
                }
                return;
            }

            int ret;

            try
            {
                if (_writeEventArgs.SocketError != SocketError.Success)
                {
                    throw new System.Net.Sockets.SocketException((int)_writeEventArgs.SocketError);
                }
                ret = _writeEventArgs.BytesTransferred;
                _writeEventArgs.SetBuffer(null, 0, 0);
                if (_writeEventArgs.BufferList != null && _writeEventArgs.BufferList != buffer)
                {
                    _writeEventArgs.BufferList.Clear();
                }
                _writeEventArgs.BufferList = null;
            }
            catch (System.Net.Sockets.SocketException ex)
            {
                if (Network.ConnectionLost(ex))
                {
                    throw new ConnectionLostException(ex);
                }
                else
                {
                    throw new Ice.SocketException(ex);
                }
            }

            if (ret == 0)
            {
                throw new ConnectionLostException();
            }

            Debug.Assert(ret > 0);
            Debug.Assert(ret == buffer.GetByteCount());
            offset = ret;
            return;
        }
コード例 #18
0
ファイル: UdpTransceiver.cs プロジェクト: yssource/ice
        public int Write(IList <ArraySegment <byte> > buffer, ref int offset)
        {
            int count     = buffer.GetByteCount();
            int remaining = count - offset;

            if (remaining == 0)
            {
                return(SocketOperation.None);
            }

            Debug.Assert(_fd != null && _state >= StateConnected);

            // The caller is supposed to check the send size before by calling checkSendSize
            Debug.Assert(Math.Min(MaxPacketSize, _sndSize - UdpOverhead) >= count);

            int ret;

            while (true)
            {
                try
                {
                    if (_state == StateConnected)
                    {
                        ret = _fd.Send(buffer, SocketFlags.None);
                    }
                    else
                    {
                        if (_peerAddr == null)
                        {
                            throw new Ice.SocketException();
                        }

                        ArraySegment <byte> data = buffer.GetSegment(0, count);
                        ret = _fd.SendTo(data.Array, 0, data.Count, SocketFlags.None, _peerAddr);
                        Debug.Assert(ret == count);
                    }
                    offset += ret;
                    break;
                }
                catch (System.Net.Sockets.SocketException ex)
                {
                    if (Network.Interrupted(ex))
                    {
                        continue;
                    }

                    if (Network.WouldBlock(ex))
                    {
                        return(SocketOperation.Write);
                    }

                    if (Network.ConnectionLost(ex))
                    {
                        throw new Ice.ConnectionLostException(ex);
                    }
                    else
                    {
                        throw new Ice.SocketException(ex);
                    }
                }
            }
            return(SocketOperation.None);
        }
コード例 #19
0
        public int Write(Buffer buf)
        {
            if (!buf.B.HasRemaining())
            {
                return(SocketOperation.None);
            }

            Debug.Assert(buf.B.Position() == 0);
            Debug.Assert(_fd != null && _state >= StateConnected);

            // The caller is supposed to check the send size before by calling checkSendSize
            Debug.Assert(Math.Min(MaxPacketSize, _sndSize - UdpOverhead) >= buf.Size());

            int ret;

            while (true)
            {
                try
                {
                    if (_state == StateConnected)
                    {
                        ret = _fd.Send(buf.B.RawBytes(), 0, buf.Size(), SocketFlags.None);
                    }
                    else
                    {
                        if (_peerAddr == null)
                        {
                            throw new Ice.SocketException();
                        }
                        ret = _fd.SendTo(buf.B.RawBytes(), 0, buf.Size(), SocketFlags.None, _peerAddr);
                    }
                    break;
                }
                catch (SocketException ex)
                {
                    if (Network.Interrupted(ex))
                    {
                        continue;
                    }

                    if (Network.WouldBlock(ex))
                    {
                        return(SocketOperation.Write);
                    }

                    if (Network.ConnectionLost(ex))
                    {
                        throw new Ice.ConnectionLostException(ex);
                    }
                    else
                    {
                        throw new Ice.SocketException(ex);
                    }
                }
                catch (Exception e)
                {
                    throw new Ice.SyscallException(e);
                }
            }

            Debug.Assert(ret > 0);
            Debug.Assert(ret == buf.B.Limit());
            buf.B.Position(buf.B.Limit());
            return(SocketOperation.None);
        }
コード例 #20
0
        public int Read(Buffer buf, ref bool hasMoreData)
        {
            if (!buf.B.HasRemaining())
            {
                return(SocketOperation.None);
            }

            Debug.Assert(buf.B.Position() == 0);
            Debug.Assert(_fd != null);

            int packetSize = Math.Min(MaxPacketSize, _rcvSize - UdpOverhead);

            buf.Resize(packetSize, true);
            buf.B.Position(0);

            int ret;

            while (true)
            {
                try
                {
                    EndPoint?peerAddr = _peerAddr;
                    if (peerAddr == null)
                    {
                        if (_addr.AddressFamily == AddressFamily.InterNetwork)
                        {
                            peerAddr = new IPEndPoint(IPAddress.Any, 0);
                        }
                        else
                        {
                            Debug.Assert(_addr.AddressFamily == AddressFamily.InterNetworkV6);
                            peerAddr = new IPEndPoint(IPAddress.IPv6Any, 0);
                        }
                    }

                    // TODO: Workaround for https://github.com/dotnet/corefx/issues/31182
                    if (_state == StateConnected ||
                        (AssemblyUtil.IsMacOS && _fd.AddressFamily == AddressFamily.InterNetworkV6 && _fd.DualMode))
                    {
                        ret = _fd.Receive(buf.B.RawBytes(), 0, buf.B.Limit(), SocketFlags.None);
                    }
                    else
                    {
                        ret       = _fd.ReceiveFrom(buf.B.RawBytes(), 0, buf.B.Limit(), SocketFlags.None, ref peerAddr);
                        _peerAddr = (IPEndPoint)peerAddr;
                    }
                    break;
                }
                catch (SocketException e)
                {
                    if (Network.RecvTruncated(e))
                    {
                        // The message was truncated and the whole buffer is filled. We ignore
                        // this error here, it will be detected at the connection level when
                        // the Ice message size is checked against the buffer size.
                        ret = buf.Size();
                        break;
                    }

                    if (Network.Interrupted(e))
                    {
                        continue;
                    }

                    if (Network.WouldBlock(e))
                    {
                        return(SocketOperation.Read);
                    }

                    if (Network.ConnectionLost(e))
                    {
                        throw new Ice.ConnectionLostException();
                    }
                    else
                    {
                        throw new Ice.SocketException(e);
                    }
                }
                catch (Exception e)
                {
                    throw new Ice.SyscallException(e);
                }
            }

            if (ret == 0)
            {
                throw new Ice.ConnectionLostException();
            }

            if (_state == StateNeedConnect)
            {
                Debug.Assert(_incoming);

                //
                // If we must connect, then we connect to the first peer that sends us a packet.
                //
                Debug.Assert(_peerAddr != null);
                bool connected = Network.DoConnect(_fd, _peerAddr, null);
                Debug.Assert(connected);
                _state = StateConnected; // We're connected now

                if (_instance.TraceLevel >= 1)
                {
                    _instance.Logger.Trace(_instance.TraceCategory, $"connected {Transport()} socket\n{this}");
                }
            }

            buf.Resize(ret, true);
            buf.B.Position(ret);

            return(SocketOperation.None);
        }
コード例 #21
0
        public void FinishRead(Buffer buf)
        {
            if (_fd == null)
            {
                return;
            }

            int ret;

            try
            {
                if (_readEventArgs.SocketError != SocketError.Success)
                {
                    throw new SocketException((int)_readEventArgs.SocketError);
                }
                ret = _readEventArgs.BytesTransferred;
                // TODO: Workaround for https://github.com/dotnet/corefx/issues/31182
                if (_state != StateConnected &&
                    !(AssemblyUtil.IsMacOS && _fd.AddressFamily == AddressFamily.InterNetworkV6 && _fd.DualMode))
                {
                    _peerAddr = _readEventArgs.RemoteEndPoint;
                }
            }
            catch (SocketException ex)
            {
                if (Network.RecvTruncated(ex))
                {
                    // The message was truncated and the whole buffer is filled. We ignore
                    // this error here, it will be detected at the connection level when
                    // the Ice message size is checked against the buffer size.
                    ret = buf.Size();
                }
                else
                {
                    if (Network.ConnectionLost(ex))
                    {
                        throw new Ice.ConnectionLostException(ex);
                    }

                    if (Network.ConnectionRefused(ex))
                    {
                        throw new Ice.ConnectionRefusedException(ex);
                    }
                    else
                    {
                        throw new Ice.SocketException(ex);
                    }
                }
            }

            if (ret == 0)
            {
                throw new Ice.ConnectionLostException();
            }

            Debug.Assert(ret > 0);

            if (_state == StateNeedConnect)
            {
                Debug.Assert(_incoming);

                //
                // If we must connect, then we connect to the first peer that
                // sends us a packet.
                //
                bool connected = !_fd.ConnectAsync(_readEventArgs);
                Debug.Assert(connected);
                _state = StateConnected; // We're connected now

                if (_instance.TraceLevel >= 1)
                {
                    _instance.Logger.Trace(_instance.TraceCategory, $"connected {Transport()} socket\n{this}");
                }
            }

            buf.Resize(ret, true);
            buf.B.Position(ret);
        }
コード例 #22
0
        public bool StartWrite(Buffer buf, AsyncCallback callback, object state, out bool completed)
        {
            Debug.Assert(_fd != null);
            Debug.Assert(_writeEventArgs != null);

            if (!_incoming && _state < StateConnected)
            {
                Debug.Assert(_addr != null);
                completed = false;
                if (_sourceAddr != null)
                {
                    _fd.Bind(_sourceAddr);
                }
                _writeEventArgs.UserToken = state;
                return(!_fd.ConnectAsync(_writeEventArgs));
            }

            // The caller is supposed to check the send size before by calling checkSendSize
            Debug.Assert(Math.Min(MaxPacketSize, _sndSize - UdpOverhead) >= buf.Size());

            Debug.Assert(buf.B.Position() == 0);

            bool completedSynchronously;

            try
            {
                _writeCallback = callback;

                if (_state == StateConnected)
                {
                    _writeEventArgs.UserToken = state;
                    _writeEventArgs.SetBuffer(buf.B.RawBytes(), 0, buf.B.Limit());
                    completedSynchronously = !_fd.SendAsync(_writeEventArgs);
                }
                else
                {
                    if (_peerAddr == null)
                    {
                        throw new Ice.SocketException();
                    }
                    _writeEventArgs.RemoteEndPoint = _peerAddr;
                    _writeEventArgs.UserToken      = state;
                    _writeEventArgs.SetBuffer(buf.B.RawBytes(), 0, buf.B.Limit());
                    completedSynchronously = !_fd.SendToAsync(_writeEventArgs);
                }
            }
            catch (SocketException ex)
            {
                if (Network.ConnectionLost(ex))
                {
                    throw new Ice.ConnectionLostException(ex);
                }
                else
                {
                    throw new Ice.SocketException(ex);
                }
            }

            completed = true;
            return(completedSynchronously);
        }