【问题标题】:Why isn't my server accessible outside of my computer?为什么在我的计算机之外无法访问我的服务器?
【发布时间】:2012-06-05 18:04:20
【问题描述】:

我在 VB.net 中创建了一个 Http Server。对于每个需要 Http Server 的项目(最近不少),我猜你可能会说,我使用了相同的“模板”。问题是,我现在正在使用的这个要求局域网上的计算机能够连接到它。我可以使用: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 仍然打开...

【问题讨论】:

  • @SteveDog 好问题。没有。:)
  • 考虑以后只发布相关代码...
  • @pst 这都是相关的。我只发布了服务器的代码。我不确定是哪个部分导致了问题,所以我发布了所有可能导致问题的部分。
  • 你试过.Prefixes.Add(String.Format("http://*:{0}/", PORT.ToString))而不是.Prefixes.Add(String.Format("https://*:{0}/", PORT.ToString))

标签: vb.net httpserver


【解决方案1】:

您无法在 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"

【讨论】:

  • 我已经直截了当它仍然无法正常工作。同时,我还在本地 IP 地址的 8001 端口上运行了一个商业服务器,它运行良好。我尝试使用http://192.168.1.1:8002 连接到我的计算机服务器。商业服务器工作正常,但我的不行。
  • 所以你把.Prefixes.Add("http://127.0.0.1:" & PORT.ToString & "/")改成.Prefixes.Add("http://192.168.1.1:" & PORT.ToString & "/")还是不行?
  • @XanderLamkins 为什么在 https 前缀上有星号,但在 http 前缀上没有?您是否尝试将 http 前缀更改为也使用星号而不是特定的 IP 地址?您是否尝试过使用 + 而不是 *?
  • 192.168.1.1 是私人地址。只有本地网络上的计算机才能访问该地址。它不是通过互联网路由的。
  • @RobertBeaubien 他没有说他试图通过互联网访问它,尽管这是一个好点。但是,如果那是他的 IP 地址,那就是要监听的 IP 地址。这甚至可以用于互联网流量。由路由器将这些消息正确路由到该私有 IP 地址。这提出了一个很好的观点,如果他试图通过路由器进行操作,他需要确保路由器不会阻塞该端口,并且他需要确保每个人都通过路由器的公共 IP 访问他的计算机,而不是他的私人的。
【解决方案2】:

http://127.0.0.1:8002/中,你的电脑地址是127.0.0.1

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

  • 127.0.0.1:这只能在您自己的计算机上使用。

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

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

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

但是,只要您的服务器位于没有固定 IP 地址的专用网络上,您的服务器可能不会像 http://www.ovh.co.uk/(或另一家,这只是一个例子)。在将您的地址提供给您的商业合作伙伴之前,您应该选择众多命名和托管服务之一,其中大多数都非常便宜。

【讨论】:

    猜你喜欢
    • 2015-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-01
    • 1970-01-01
    • 2020-11-14
    • 2011-12-10
    • 1970-01-01
    相关资源
    最近更新 更多