2010-03-02 120 views
0

我有一個繼承自TcpListener的類,這個類僅僅調用Start()方法和BeginAcceptTcpClient()方法。有時會調用該方法,但端口未打開(netstat不顯示端口打開)。TcpListener.Start()不打開端口

類看起來像這樣

Public Class ExtendedTcpListener 
    Inherits System.Net.Sockets.TcpListener 

Public Shadows Sub Start() 
    SyncLock (m_stopLock) 
     MyBase.Start() 
     MyBase.BeginAcceptTcpClient(AddressOf Me.CompleteAcceptTcpClient, Me) 
     My.Application.Log.WriteEntry("Extended Tcp Listener started ...", TraceEventType.Verbose) 
    End SyncLock 
End Sub 

上發生了什麼或如何調試問題的任何想法?由於Start()被無例外地調用,我期望找到始終打開的端口(日誌總是被寫入)。

額外信息:當Start方法正常工作時,它每次都有效,直到應用程序重新啓動。當Start方法不起作用時,在應用程序重新啓動之前它不會再工作。

編輯:還有在ExtendedTcpListener一個Stop方法:

Public Shadows Sub [Stop]() 
    SyncLock (m_stopLock) 
     MyBase.Stop() 
     My.Application.Log.WriteEntry("... extended Tcp Listener stopped", TraceEventType.Verbose) 
    End SyncLock 
End Sub 

使用該ExtendedTcpListener此類實現IDisposable模式和處置內部的ExtendedTcpListener.Stop被調用。

問題發生時,日誌中不存在停止文本。

回答

0

難道第一次啓動被調用其他方法/線程獲取m_stopLock鎖嗎? (什麼類型的對象是m_stopLock?)

你可以看看調試器,看看是否調用陰影構造函數? (或者在SynchLock之前設置跟蹤)

+0

不。當「Extended Tcp Listener started ...」字符串被寫入時,到達那裏時不會執行鎖定。 m_stopLock是主要用作啓動和停止鎖定的對象,以避免同時啓動和停止。 – 2010-03-02 12:19:14

+0

你是什麼意思,「你可以看看調試器,看看是否調用陰影構造函數?」。基礎構造函數總是被調用,因爲我唯一的構造函數調用Mybase.New() – 2010-03-02 12:20:40

+0

所以我明白:問題不在於某些代碼沒有得到執行(MyBase.BeginAcceptTcpClient(AddressOf Me.CompleteAcceptTcpClient,Me)),我認爲 - 但是,儘管代碼得到執行,但端口仍未打開。它是否正確? – Ando 2010-03-02 12:25:24

0

難道你不是很快處置對象嗎?

我們可以在哪裏看到創建ExtendedTcpListener實例的代碼,以及如何管理它?

+0

這將是非常罕見的,因爲它僅用於實現IDisposable的另一個類,並且此類將調用ExtendedTcpListener Stop方法,該方法具有另一個寫入「Extended Tcp Listener Stopped ...」的日誌(當然,該文本不存在問題發生)。無論如何,我會把代碼作爲一個編輯。 – 2010-03-17 07:36:01

0

這是一個奇怪的,沒關係。據我所知,一旦問題開始出現,你可以很容易地重現它,對嗎?如果是這樣,那麼我會在此時將調試器附加到它,並檢查TcpListener對象及其底層套接字(m_ServerSocket)。我沒有給出準確的指示,你只需要看看它,看看有什麼東西看起來不合適,或者與事情發生的方式不同。

0

對於我來說,從TcpListener繼承並使用Shadows覆蓋非虛擬方法對我而言非常危險。你有沒有試圖改變你的代碼不從TcpListener繼承,但只是封裝它?

編輯:加入樣品代碼

Public Class ExtendedTcpListener 
    ' Inherits System.Net.Sockets.TcpListener <== DO NOT INHERIT 

    Private MyTcpListener As New TcpListener() 

    Public Sub Start() 
    SyncLock (m_stopLock) 
     MyTcpListener.Start() 
     MyTcpListener.BeginAcceptTcpClient(AddressOf Me.CompleteAcceptTcpClient, Me) 
     My.Application.Log.WriteEntry("Extended Tcp Listener started ...", TraceEventType.Verbose) 
    End SyncLock 
    End Sub 

    ' ... 
End Class 
+0

爲什麼看起來很危險?陰影是爲了用這種方式是不是? – 2010-03-23 13:59:51

+0

陰影就像在非虛擬(非可繼承)方法上「強制」重寫一樣。這會中斷多態:如果將ExtendedTcpListener傳遞給期望使用TcpListener的方法(或者僅將其分配給聲明爲TcpListener的變量),則將調用TcpListener類的Start和Stop方法,而不是您的重寫。 「陰影」是邪惡的,避免它像地獄 - 試圖封裝而不是繼承這種方式。 – 2010-03-23 17:13:25

+0

好的,我明白了這一點,無論如何,這不是問題,因爲這個類總是作爲ExtendedTcpListener使用,只能使用一次。不管怎麼說,還是要謝謝你。 – 2010-03-24 11:14:53