2010-03-02 2 views
0

TcpListener에서 상속하는 클래스가 있습니다.이 클래스는 Start 메서드를 그림자 만 사용하여 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 메소드가 작동하지 않으면 앱이 다시 시작될 때까지 다시 작동하지 않습니다.

편집 :

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가 호출 : 또한 ExtendedTcpListener에서 정지 방법이있다.

문제가 발생하면 로그에 중지 텍스트가 없습니다.

답변

0

처음 시작할 때 Start가 다른 메서드라고하면/thread가 m_stopLock에 잠금을 설정합니까? (어떤 유형의 객체가 m_stopLock입니까?)

디버거를보고 섀도 잉 생성자가 호출되는지 확인할 수 있습니까? (또는 SynchLock 전에 추적을 설정하십시오)

+0

아니. "Extended Tcp Listener started ..."문자열이 작성되면 거기에 도달 할 때 잠금이 수행되지 않습니다. m_stopLock는, 개시 및 정지를 동시에 피하기 위해서, 주로 개시 및 정지 락으로서 사용되는 Object입니다. –

+0

"디버거를보고 그림자 생성자가 호출되는지 확인할 수 있습니까?"라는 의미는 무엇입니까? 내 유일한 생성자가 Mybase.New()를 호출하기 때문에 항상 기본 생성자가 호출됩니다. –

+0

그래서 이해합니다. 문제는 일부 코드가 실행되지 않는다는 것 (MyBase.BeginAcceptTcpClient (AddressOf Me.CompleteAcceptTcpClient, Me))입니다. 그러나 코드가 실행 되더라도 포트는 여전히 열려 있지 않습니다. 이 올바른지? – Ando

0

개체를 너무 빨리 처분하지 않습니까?

ExtendedTcpListener의 인스턴스를 생성하고 관리하는 코드를 볼 수 있습니까?

+0

IDisposable을 구현하는 다른 클래스에서만 사용되며이 클래스는 "Extended Tcp Listener Stopped ..."라고 쓰는 다른 로그가있는 ExtendedTcpListener Stop 메서드를 호출하기 때문에 매우 드뭅니다 (이 텍스트는 물론 문제가 발생 함). 어쨌든 나는 코드를 수정으로 넣을 것이다. –

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

왜 위험 해 보입니까? 그림자는 이런 식으로 사용하기위한 것입니다. –

+0

그림자는 가상이 아닌 (상속받지 않는) 메서드에서 재정의를 "강요하는"것과 같습니다. 이렇게하면 다형성이 깨집니다. ExtendedTcpListener를 TcpListener가 필요한 메서드에 전달하면 (또는 단순히 TcpListener로 선언 된 변수에 할당하면) 재정의 대신 TcpListener 클래스의 Start 및 Stop 메서드가 호출됩니다. "그림자"는 악마 같아서 지옥처럼 피하십시오 - 이런 식으로 상속하는 대신에 캡슐화하십시오. –

+0

클래스는 항상 ExtendedTcpListener로 사용되며 한 번만 사용되기 때문에 여기서는 문제가 아닙니다. 어쨌든 고마워. –

관련 문제