/// <summary> /// Like /// <see cref="Connect(System.Net.Sockets.Socket, System.Net.EndPoint, int)"/> /// but /// also takes a local address and port to bind the socket to. /// </summary> /// <param name="socket"/> /// <param name="endpoint">the remote address</param> /// <param name="localAddr">the local address to bind the socket to</param> /// <param name="timeout">timeout in milliseconds</param> /// <exception cref="System.IO.IOException"/> public static void Connect(Socket socket, EndPoint endpoint, EndPoint localAddr, int timeout) { if (socket == null || endpoint == null || timeout < 0) { throw new ArgumentException("Illegal argument for connect()"); } SocketChannel ch = socket.GetChannel(); if (localAddr != null) { Type localClass = localAddr.GetType(); Type remoteClass = endpoint.GetType(); Preconditions.CheckArgument(localClass.Equals(remoteClass), "Local address %s must be of same family as remote address %s." , localAddr, endpoint); socket.Bind2(localAddr); } try { if (ch == null) { // let the default implementation handle it. socket.Connect(endpoint, timeout); } else { SocketIOWithTimeout.Connect(ch, endpoint, timeout); } } catch (SocketTimeoutException ste) { throw new ConnectTimeoutException(ste.Message); } // There is a very rare case allowed by the TCP specification, such that // if we are trying to connect to an endpoint on the local machine, // and we end up choosing an ephemeral port equal to the destination port, // we will actually end up getting connected to ourself (ie any data we // send just comes right back). This is only possible if the target // daemon is down, so we'll treat it like connection refused. if (socket.GetLocalPort() == socket.GetPort() && socket.GetLocalAddress().Equals( socket.GetInetAddress())) { Log.Info("Detected a loopback TCP socket, disconnecting it"); socket.Close(); throw new ConnectException("Localhost targeted connection resulted in a loopback. " + "No daemon is listening on the target port."); } }
/// <summary>Create a new ouput stream with the given timeout.</summary> /// <remarks> /// Create a new ouput stream with the given timeout. If the timeout /// is zero, it will be treated as infinite timeout. The socket's /// channel will be configured to be non-blocking. /// </remarks> /// <param name="channel"> /// /// Channel for writing, should also be a /// <see cref="SelectableChannel"/> /// . /// The channel will be configured to be non-blocking. /// </param> /// <param name="timeout">timeout in milliseconds. must not be negative.</param> /// <exception cref="System.IO.IOException"/> public SocketOutputStream(WritableByteChannel channel, long timeout) { SocketIOWithTimeout.CheckChannelValidity(channel); writer = new SocketOutputStream.Writer(channel, timeout); }
/// <summary>Create a new input stream with the given timeout.</summary> /// <remarks> /// Create a new input stream with the given timeout. If the timeout /// is zero, it will be treated as infinite timeout. The socket's /// channel will be configured to be non-blocking. /// </remarks> /// <param name="channel"> /// /// Channel for reading, should also be a /// <see cref="SelectableChannel"/> /// . /// The channel will be configured to be non-blocking. /// </param> /// <param name="timeout">timeout in milliseconds. must not be negative.</param> /// <exception cref="System.IO.IOException"/> public SocketInputStream(ReadableByteChannel channel, long timeout) { SocketIOWithTimeout.CheckChannelValidity(channel); reader = new SocketInputStream.Reader(channel, timeout); }