none
請問如何偵測建立SOCKET連線失敗? RRS feed

  • 問題

  • 如提,

     

    ClientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)


    Dim address As IPAddress = System.Net.Dns.GetHostEntry(Me.TextBox1.Text).AddressList(0)
    Dim endpoint As New IPEndPoint(address, CInt(Me.TextBox2.Text))


    ClientSocket.BeginConnect(endpoint, New AsyncCallback(AddressOf Connected), Nothing)

     

    如果伺服端沒有開啟時該如何判斷?

     

    2008年12月10日 上午 05:35

解答

  •  

    You can specify both send and receive timeouts using
    Socket.SetSocketOption(), e.g.


    int timeout = 2000; // in milliseconds
    socket.SetSocketOption(
        SocketOptionLevel.Socket,
        SocketOptionName.SendTimeout,
        timeout);

    Cheers,
    2008年12月10日 上午 08:07
  • 內網 2 秒是還好,網際網路 2 秒太短了...

     

    我自己用 5 ~ 15 秒。

     

    2008年12月10日 上午 10:16
  • send/receive timeout 對非同步無效,
    beginconnect 無論有沒有連線成功都會進 callback function,
    在這裡頭看 socket 的 connected 屬性即可,

    使用非同步 socket 時, 我自己會關閉 socket 的時機有幾個,

    1. beginreceive 取得 socketerror 如果不是 success,
    2. endreceive 取得 socketerror 如果不是 success ,
    3. 回傳值為 0 byte, 且 socket.poll(1,selectread) 為 true 時,
    4. beginsend 取得 socketerror 如果不是 success,
    5. endsend 取得 socketerror 如果不是 success,
    6. 我自己的 timer 會設一個 time out , 在我設定的秒數內沒有成功 send/receive data 時,

    使用 socket 時, 都做 synclock 保護, 判斷是否連線直接看實體變數是否變成 nothing,
    在下完 shutdown, close 後馬上把實體變數設為 nothing,


    2008年12月10日 上午 11:00

所有回覆

  •  

    You can specify both send and receive timeouts using
    Socket.SetSocketOption(), e.g.


    int timeout = 2000; // in milliseconds
    socket.SetSocketOption(
        SocketOptionLevel.Socket,
        SocketOptionName.SendTimeout,
        timeout);

    Cheers,
    2008年12月10日 上午 08:07
  • 內網 2 秒是還好,網際網路 2 秒太短了...

     

    我自己用 5 ~ 15 秒。

     

    2008年12月10日 上午 10:16
  • send/receive timeout 對非同步無效,
    beginconnect 無論有沒有連線成功都會進 callback function,
    在這裡頭看 socket 的 connected 屬性即可,

    使用非同步 socket 時, 我自己會關閉 socket 的時機有幾個,

    1. beginreceive 取得 socketerror 如果不是 success,
    2. endreceive 取得 socketerror 如果不是 success ,
    3. 回傳值為 0 byte, 且 socket.poll(1,selectread) 為 true 時,
    4. beginsend 取得 socketerror 如果不是 success,
    5. endsend 取得 socketerror 如果不是 success,
    6. 我自己的 timer 會設一個 time out , 在我設定的秒數內沒有成功 send/receive data 時,

    使用 socket 時, 都做 synclock 保護, 判斷是否連線直接看實體變數是否變成 nothing,
    在下完 shutdown, close 後馬上把實體變數設為 nothing,


    2008年12月10日 上午 11:00
  • 非常感謝各位大大寶貴的經驗, 不知能否提供簡單實列供參考 謝謝!!! 

    2008年12月11日 上午 01:41
  • VB.net Saqmple Code

    Code Snippet

     

    Class TimeOutSocket
        Private Shared IsConnectionSuccessful As Boolean = False
        Private Shared socketexception As Exception
        Private Shared TimeoutObject As New ManualResetEvent(False)
       
        Public Shared Function Connect(ByVal remoteEndPoint As IPEndPoint, ByVal timeoutMSec As Integer) As TcpClient
            TimeoutObject.Reset()
            socketexception = Nothing
           
            Dim serverip As String = Convert.ToString(remoteEndPoint.Address)
            Dim serverport As Integer = remoteEndPoint.Port
            Dim tcpclient As New TcpClient()
           
            tcpclient.BeginConnect(serverip, serverport, New AsyncCallback(CallBackMethod), tcpclient)
           
            If TimeoutObject.WaitOne(timeoutMSec, False) Then
                If IsConnectionSuccessful Then
                    Return tcpclient
                Else
                    Throw socketexception
                End If
            Else
                tcpclient.Close()
                Throw New TimeoutException("TimeOut Exception")
            End If
        End Function
        Private Shared Sub CallBackMethod(ByVal asyncresult As IAsyncResult)
            Try
                IsConnectionSuccessful = False
                Dim tcpclient As TcpClient = TryCast(asyncresult.AsyncState, TcpClient)
               
                If tcpclient.Client IsNot Nothing Then
                    tcpclient.EndConnect(asyncresult)
                    IsConnectionSuccessful = True
                End If
            Catch ex As Exception
                IsConnectionSuccessful = False
                socketexception = ex
            Finally
                TimeoutObject.Set()
            End Try
        End Sub
    End Class

     

     

     

     

    C# Sample Code

    Code Snippet

     

    class TimeOutSocket
    {
        private static bool IsConnectionSuccessful = false;
        private static Exception socketexception;
        private static ManualResetEvent TimeoutObject = new ManualResetEvent(false);
    
        public static TcpClient Connect(IPEndPoint remoteEndPoint, int timeoutMSec)
        {
            TimeoutObject.Reset();
            socketexception = null;  
    
            string serverip = Convert.ToString(remoteEndPoint.Address);
            int serverport = remoteEndPoint.Port;           
            TcpClient tcpclient = new TcpClient();
            
            tcpclient.BeginConnect(serverip, serverport, 
    			new AsyncCallback(CallBackMethod), tcpclient);
    
            if (TimeoutObject.WaitOne(timeoutMSec, false))
            {
                if (IsConnectionSuccessful)
                {
                    return tcpclient;
                }
                else
                {
                    throw socketexception;
                }
            }
            else
            {
                tcpclient.Close();
                throw new TimeoutException("TimeOut Exception");
            }
        }
        private static void CallBackMethod(IAsyncResult asyncresult)
        {
            try
            {
                IsConnectionSuccessful = false;
                TcpClient tcpclient = asyncresult.AsyncState as TcpClient;
                 
                if (tcpclient.Client != null)
                {
                    tcpclient.EndConnect(asyncresult);
                    IsConnectionSuccessful = true;
                }
            }
            catch (Exception ex)
            {
                IsConnectionSuccessful = false;
                socketexception = ex;
            }
            finally
            {
                TimeoutObject.Set();
            }
        }
    }

     

     

     

    2008年12月11日 上午 01:49
  • 感謝CMF!!!

     

    2008年12月12日 上午 01:14