为什么我的服务器不能在我的计算机外访问?

时间:2012-06-05 18:04:20

标签: vb.net httpserver

我在VB.net中创建了一个Http Server。我想你可以说,对于每个需要Http Server的项目(最近都有很多),我使用了相同的“模板”。问题是,我现在正在使用的这个要求LAN上的计算机能够连接到它。我可以直接从我的计算机访问服务器,但使用:http://127.0.0.1:8002/。这是我的源代码(当然是略读):

Imports System.Net
Imports System.IO
Imports System.Web
Imports System.Text
Imports System.Text.RegularExpressions
Imports Microsoft.Win32

Public Class MainWindow

    Private Enum ApplicationSituation
        Idle
        Login
        TrackPage
    End Enum

    Private CurrentApplicationSituation As ApplicationSituation = ApplicationSituation.Idle

    Private listener As New HttpListener
    Private theService As String

    Private Const PORT As Integer = 8002
    Private Const SERVERNAME As String = "Poptimas"

    Private ContentTypes As New Dictionary(Of String, String)

    Private ServerThread As Threading.Thread

    Private Sub WriteContentTypes()
        '(TEXT) Human-readable text and source code
        ContentTypes.Add(".txt", "text/plain")
        ContentTypes.Add(".htm", "text/html")
        ContentTypes.Add(".html", "text/html")
        ContentTypes.Add(".xml", "text/xml")
        ContentTypes.Add(".css", "text/css")
        ContentTypes.Add(".csv", "text/scv")
        ContentTypes.Add(".htc", "text/x-component")
        ContentTypes.Add(".js", "application/javascript")
        '(IMAGE)
        ContentTypes.Add(".png", "image/png")
        ContentTypes.Add(".jpg", "image/jpg")
        ContentTypes.Add(".bmp", "image/bmp")
        ContentTypes.Add(".gif", "image/gif")
        ContentTypes.Add(".tiff", "image/tiff")
        ContentTypes.Add(".ico", "image/vnd.microsoft.icon")
        '(AUDIO)
        ContentTypes.Add(".mp3", "audio/mp3")
        ContentTypes.Add(".wav", "audio/vnd.wav")
        ContentTypes.Add(".ogg", "audio/ogg")
        ContentTypes.Add(".mwa", "audio/x-ms-wma")
        '(VIDEO)
        ContentTypes.Add(".mp4", "video/mp4")
        ContentTypes.Add(".wmv", "video/x-ms-wmv")
        ContentTypes.Add(".mov", "video/quicktime")
        '(APPLICATION) Non-standard
        ContentTypes.Add(".pdf", "application/pds")
        ContentTypes.Add(".swf", "aplication/x-shockwave-flash")
    End Sub

    Private Function ParseQuery(ByVal queryset As String) As Dictionary(Of String, String)
        Dim FinQu As New Dictionary(Of String, String)
        If queryset.Length > 0 Then
            For Each qSet As String In queryset.Substring(1).Split("&")
                Dim sA() As String = qSet.Split("=")
                FinQu.Add(sA(0), sA(1))
            Next
        End If
        Return FinQu
    End Function

    Private Sub StartServer()
        Try
            Dim machineName As String = System.Environment.MachineName
            VariableValues.Add("port", PORT)
            VariableValues.Add("computer", machineName)
            theService = HttpUtility.UrlEncode(SERVERNAME)

            WriteContentTypes()

            With listener
                .Prefixes.Add(String.Format("https://*:{0}/", PORT.ToString))
                .Prefixes.Add("http://127.0.0.1:" & PORT.ToString & "/")
                .Start()
            End With

            Dim context As HttpListenerContext
            Dim path As String


            While listener.IsListening
                context = listener.GetContext
                path = context.Request.Url.AbsolutePath.ToLower
                Dim query As Dictionary(Of String, String) = ParseQuery(context.Request.Url.Query)
                If path = "/" Then
                    Select Case CurrentApplicationSituation
                        Case ApplicationSituation.Idle

                        Case ApplicationSituation.Login
                            SendPage(context.Response, My.Computer.FileSystem.CurrentDirectory & "/MobilePandoraConnection/login.html", ".html")
                        Case ApplicationSituation.TrackPage
                            SendPage(context.Response, My.Computer.FileSystem.CurrentDirectory & "/MobilePandoraConnection/track.html", ".html")
                    End Select
                ElseIf path = "/inject" Then
                    SendPage(context.Response, My.Computer.FileSystem.CurrentDirectory & "/MobilePandoraConnection/PandoraMediaServer.js", ".js")
                Else
                    SendPage(context.Response, My.Computer.FileSystem.CurrentDirectory & "/MobilePandoraConnection" & path, path.Substring(path.IndexOf(".")).ToLower())
                End If
            End While

            With listener
                .Stop()
                .Close()
            End With
        Catch ex As Exception
            MsgBox(ex.ToString())
        End Try
    End Sub

    Private Sub SendPage(ByVal response As HttpListenerResponse, ByVal Location As String, ByVal extension As String)

        With response
            .ContentType = ContentTypes(extension)
            .ContentEncoding = Encoding.UTF8

            Try
                Dim cont() As Byte = System.Text.Encoding.ASCII.GetBytes(page)
                Else
                    cont = My.Computer.FileSystem.ReadAllBytes(Location)
                End If
                .OutputStream.Write(cont, 0, cont.LongLength)
                .OutputStream.Flush()
            Catch ex As Exception
                MsgBox("Server Error: " & ex.ToString)
            Finally
                Try
                    .Close()
                Catch ex As Exception
                End Try
            End Try
        End With

    End Sub

    Private Sub MainWindow_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        'Stupid Server likes to keep everything running - kill that sucka'
        Process.GetCurrentProcess().Kill()
    End Sub

    Private Sub SystemPanel_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
        'Start server in new thread to prevent an un-reponsive form
        ServerThread = New Threading.Thread(AddressOf StartServer)
        ServerThread.Start()
    End Sub

End Class

如果有什么不起作用(例如,如果你试图将其直接复制并粘贴进行测试),我可能只是在我拿出一些不必要的代码时犯了一个错误。

顺便说一下:   - 我的防火墙未运行

为STEVEDOG编辑

我已将这两个前缀设为:

.Prefixes.Add(String.Format("https://*:{0}/", PORT.ToString))
.Prefixes.Add(String.Format("http://*:{0}/", PORT.ToString))

现在每次尝试应用前缀时都会出错:

  

无法侦听前缀“https:// *:8002 /”,因为它与计算机上的现有注册冲突。

我已经检查了所有正在侦听的端口,8002仍处于打开状态......

2 个答案:

答案 0 :(得分:3)

您无法侦听IP地址127.0.0.1。您需要实际监听您的真实IP地址。侦听127.0.0.1只会接收专门发送到环回地址的消息。

此外,您无法使用HttpListener在同一端口和IP地址上同时侦听http和https。有关详细信息,请参阅此链接:

.NET HttpListener: when registering both HTTP & HTTPS I get "conflicts with an existing registration on the machine"

答案 1 :(得分:0)

http://127.0.0.1:8002/中,您的计算机地址为127.0.0.1

通常有4种方式可以访问您的服务器:

  • 127.0.0.1:这只适用于您自己的计算机。

  • 192.168.1.1或类似:这只适用于您的本地网络。由于IPV4地址的数量非常有限,因此您使用的地址仅在您的LAN上有效,并且没有每个人都可以看到“永久”IP地址。 LAN上的每台计算机都有不同的本地IP地址,但世界上有许多计算机具有相同的本地地址。

  • 如果您的局域网和互联网之间的路由器配置为允许输入来自互联网的连接(这对您来说有点危险,特别是如果您的个人计算机上没有防火墙),那么您有一个IP就可以了可能知道使用许多在线服务,如http://www.knowmyip.com/。此地址是临时的,将在您的下一次连接时更改(因为没有足够的IPV4地址)

  • 一个名称,使用像http://dyn.com/dns/这样的服务,它为每个人提供常量名称和服务器之间的动态链接。这样人们就可以使用http://keods.dyndns.org之类的内容访问您的服务器,而不是询问您当前的IP地址是什么。

但只要您的服务器位于没有修复IP地址的专用网络上,您的服务器可能就不会像专用公司(例如http://www.ovh.co.uk/(或其他公司)专门托管的服务器那样容易访问只是一个例子)。在您向商业合作伙伴提供地址之前,您应该选择众多的命名和托管服务之一,其中大多数都非常便宜。