2010-03-02 117 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