| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -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; | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |