|
|
@ -593,6 +593,48 @@ namespace Apewer |
|
|
|
|
|
|
|
#region Socket
|
|
|
|
|
|
|
|
/// <summary>发起连接。</summary>
|
|
|
|
/// <param name="socket">套接字。</param>
|
|
|
|
/// <param name="endpoint">远程终结点。</param>
|
|
|
|
/// <param name="timeout">连接超时毫秒数。当达到指定时长,或达到系统默认时长时,将会发生超时异常。</param>
|
|
|
|
/// <exception cref="ArgumentNullException"></exception>
|
|
|
|
/// <exception cref="SocketException"></exception>
|
|
|
|
public static void Connect(this Socket socket, IPEndPoint endpoint, int timeout) |
|
|
|
{ |
|
|
|
if (socket == null) throw new ArgumentNullException(nameof(socket)); |
|
|
|
if (endpoint == null) throw new ArgumentNullException(nameof(endpoint)); |
|
|
|
if (timeout < 1) throw new ArgumentOutOfRangeException(nameof(timeout)); |
|
|
|
|
|
|
|
var connecting = true; |
|
|
|
if (timeout > 0) |
|
|
|
{ |
|
|
|
RuntimeUtility.InBackground(timeout, () => |
|
|
|
{ |
|
|
|
if (connecting && !socket.Connected) |
|
|
|
{ |
|
|
|
socket.Close(); |
|
|
|
#if !NET20
|
|
|
|
socket.Dispose(); |
|
|
|
#endif
|
|
|
|
} |
|
|
|
}, true); |
|
|
|
} |
|
|
|
try |
|
|
|
{ |
|
|
|
socket.Connect(endpoint); |
|
|
|
} |
|
|
|
catch (SocketException ex) |
|
|
|
{ |
|
|
|
if (ex.SocketErrorCode == SocketError.NotSocket) |
|
|
|
{ |
|
|
|
throw new SocketException((int)SocketError.TimedOut); |
|
|
|
} |
|
|
|
// throw new Exception($"{ex.ErrorCode} {ex.SocketErrorCode}: {ex.Message}");
|
|
|
|
throw; |
|
|
|
} |
|
|
|
connecting = false; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>检查 Socket 在线状态。</summary>
|
|
|
|
/// <exception cref="NotSupportedException"></exception>
|
|
|
|
/// <exception cref="ObjectDisposedException"></exception>
|
|
|
@ -601,7 +643,7 @@ namespace Apewer |
|
|
|
{ |
|
|
|
if (socket == null) return false; |
|
|
|
|
|
|
|
var pending = socket.Poll(1000, System.Net.Sockets.SelectMode.SelectRead); |
|
|
|
var pending = socket.Poll(1000, SelectMode.SelectRead); |
|
|
|
var available = socket.Available; |
|
|
|
var offline = pending && available == 0; |
|
|
|
return !offline; |
|
|
|