vb.nethosts-file

Application taking a while to listen for incoming connections


I have an application which uses the hosts file to block certain websites. The websites can't connect because of the hosts file, so that works great, however, my program is supposed to raise an event when a website is blocked.

I'm using this code:

Private Sub Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    Dim blocker As BlockListener
        Dim thread As Thread
        blocker = New BlockListener
        thread = New Thread(New ThreadStart(AddressOf blocker.listen))
        thread.Start()

    AddHandler blocker.Blocked, AddressOf User_Blocked
End Sub


Private Sub User_Blocked()
    My.Computer.Audio.Play("Sounds\Website-Blocked.wav")
    WebsiteDetected.ShowDialog()
    SetForegroundWindow(WebsiteDetected.Handle)
End Sub

Public Class BlockListener

    Private port As Integer = 80

    Private listener As TcpListener

    Private BlockUsers As Boolean = True
    Public Event Blocked As EventHandler

    Public Sub listen()
        listener = New TcpListener(IPAddress.Parse("127.0.0.1"), port)
        listener.Start()
        While (BlockUsers)
            Dim clientConnection As TcpClient = listener.AcceptTcpClient

            clientConnection.Close()
            BlockUsers = False

            RaiseEvent Blocked(Me, EventArgs.Empty)
        End While


        listener.Stop()
    End Sub

After I wait for a while (say for about two minutes) then the program can detect bad websites that are visited, however, I don't really want to wait, as I think it's a lot more practical if you just run the program, and done, you won't have to wait for the program to start listening for incoming connections.

Is there anyway I can listen on the server quicker?

Also, could it be because I have lots of websites on my hosts file? I've got a total of 80, 000 infected websites, and since Visual Basic is a lot slower than some certain languages, could that be the reason why?


Solution

  • I don't know why the TcpListener takes such a long time to detect the connection, but I can confirm that it does.

    What seems to solve the problem is to switch to a HttpListener instead, which can be used to host an actual HTTP server.

    Finally, you need to marshal the call from User_Blocked to the UI thread before you can start opening forms and accessing UI elements. This is because your Blocked event is run in the background thread, and all UI-related code must run on the UI thread only.

    Private port As Integer = 80
    
    Private listener As New HttpListener
    
    Private BlockUsers As Boolean = True
    Public Event Blocked As EventHandler
    
    Public Sub listen()
        listener.Start()
        listener.Prefixes.Add("http://*:80/")
    
        While (BlockUsers)
            Dim context As HttpListenerContext = Listener.GetContext()
            context.Response.Close()
    
            BlockUsers = False
    
            RaiseEvent Blocked(Me, EventArgs.Empty)
        End While
    
        listener.Close()
    End Sub
    

    In your form:

    Private Sub User_Blocked()
        If Me.InvokeRequired Then 'Do we need to invoke or are we already on the UI thread?
            Me.Invoke(New MethodInvoker(AddressOf User_Blocked))
        Else 'We are on the UI thread.
            My.Computer.Audio.Play("Sounds\Website-Blocked.wav")
            WebsiteDetected.Show() 'Note that if you use ShowDialog(), the next line won't execute until the form has been closed.
            SetForegroundWindow(WebsiteDetected.Handle)
        End If
    End Sub
    

    NOTE: Your application must run with administrative privileges for the HttpListener to work.