public int Initialize(Buffer readBuffer, Buffer writeBuffer, ref bool hasMoreData) { Debug.Assert(_fd != null); if (_state == StateNeedConnect) { _state = StateConnectPending; try { if (_sourceAddr != null) { _fd.Bind(_sourceAddr); } _fd.Connect(_addr); } catch (SocketException ex) { if (Network.WouldBlock(ex)) { return(SocketOperation.Connect); } throw new Ice.ConnectFailedException(ex); } catch (Exception ex) { throw new Ice.ConnectFailedException(ex); } _state = StateConnected; } Debug.Assert(_state >= StateConnected); return(SocketOperation.None); }
public int Initialize(ref ArraySegment <byte> readBuffer, IList <ArraySegment <byte> > writeBuffer) { Debug.Assert(_fd != null); if (_state == StateNeedConnect) { _state = StateConnectPending; try { if (_sourceAddr != null) { _fd.Bind(_sourceAddr); } _fd.Connect(_addr); } catch (System.Net.Sockets.SocketException ex) { if (Network.WouldBlock(ex)) { return(SocketOperation.Connect); } throw new ConnectFailedException(ex); } catch (System.Exception ex) { throw new ConnectFailedException(ex); } _state = StateConnected; } Debug.Assert(_state >= StateConnected); return(SocketOperation.None); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }