【发布时间】:2017-01-06 03:34:23
【问题描述】:
我正在 VB.net 中开发一个我打算分发的科学软件。应用程序的一部分将涉及与服务器(和其他客户端)的通信。就所有意图和目的而言,通信就像一个聊天应用程序。
我使用套接字开发了该软件,并且在我的本地网络上在家进行测试时可以正常工作。以下是我发送消息的基本方式:
Dim serverIPString as String = "192.168.1.5"
Dim serverPort as long = 65500
dim messageString as String = "Hello"
Dim Client As New System.Net.Sockets.TcpClient(serverIPString, serverPort)
Dim Writer As System.IO.StreamWriter(Client.GetStream())
Writer.Write(messageString)
Writer.Flush()
Writer.Close()
我就是这样听的:
Public Class TCPIPListener
Dim initalised As Boolean = False
Dim port As Long
Dim IP As System.Net.IPAddress
Dim ourListener As TcpListener
Dim ourClient As TcpClient
Dim ourMessage As String
'''''''''''
'' ctors ''
'''''''''''
Public Sub New()
initalised = False
End Sub
'Takes IP and port and starts listeing
Public Sub New(inIP As String, inPort As Long, inExchange As messageExchange)
'Try to set the IP
Try
IP = System.Net.IPAddress.Parse(inIP)
Catch ex As Exception
Exit Sub
End Try
'Set the port
port = inPort
initalised = startListener()
End Sub
'''''''''''''''
'' Listening ''
'''''''''''''''
Private Sub Listening()
ourListener.Start()
End Sub
'starts listener
Public Function startListener() As Boolean
ourListener = New TcpListener(IP, port)
ourClient = New TcpClient()
Dim ListenerThread As New Thread(New ThreadStart(AddressOf Listening))
ListenerThread.Start()
initalised = True
Return True
End Function
'Called from a timer on the form
Public Function tick() As Boolean
If Not initalised Then
Return False
End If
If ourListener.Pending = True Then
ourMessage = ""
ourClient = ourListener.AcceptTcpClient()
Dim Reader As New System.IO.StreamReader(ourClient.GetStream())
While Reader.Peek > -1
ourMessage = ourMessage + Convert.ToChar(Reader.Read()).ToString
End While
messagebox(ourMessage)
End If
Return True
End Function
End Class
使用这种方法,每个客户端都将监听从服务器发送的消息,并且发送的任何消息都将发送到服务器并被定向到相关客户端 - 这有点低效,但对于我的软件工作方式来说是必要的。
问题是我很难让它在互联网上运行。如果我向本地 IP 地址发送消息,它工作正常,即使是从调试器。如果我使用外部 IP 地址,我会得到以下信息:
无法连接,因为目标机器主动拒绝 XXX.XXX.XXX.XXX:65500"
我已使用路由器打开端口转发,并设置正确的端口(此处为 65500)转发到运行 TCP 和 UDP 的列表器 (192.168.1.5) 的 PC。 This website 它告诉我这个端口是开放的,而两边都没有。
如果我右键单击 exe 并以管理员身份运行,我的防病毒软件会弹出并说当我启动侦听器时它正在做一些可疑的事情(我猜这是否令人鼓舞)。如果我随后将我的应用程序添加到异常列表并再次运行它,然后检查端口是否正在侦听(使用this)我发现我的应用程序正在侦听正确的端口(如果我停止应用程序,它就消失了) .但是,客户端应用程序仍然会出现上述相同的错误。如果我使用随机 IP 地址而不是侦听器之一,则会收到不同的错误:
{“连接尝试失败,因为连接方一段时间后没有正确响应,或者连接失败,因为连接的主机没有响应XXX.XXX.XXX.XXX:65500”}
我怀疑我没有采取正确的方法来解决这个问题。我对 VB 的大部分方面都很好,但之前还没有真正解决过这类问题。当谈到分发软件时,我真的不希望我的客户必须搞乱深度设置才能让这个应用程序工作。任何帮助都会对我非常有用!
我想我将来会面临的另一个问题是,如果多个客户端具有相同的外部 IP 但不同的内部 IP(我打算分发给大学)。在这种情况下,我猜端口转发将不起作用。
非常感谢提前(并为长篇文章道歉)!
【问题讨论】:
-
启动连接的客户端应使用随机的、空灵的端口之一作为其源端口。只有服务器应该有一个定义的端口号。一旦客户端建立了 TCP 连接,它应该保持它直到应用程序在客户端关闭。 TCP 是对等点的双向连接(没有客户端或服务器,这是一个应用概念,与 TCP 无关)。这将避免您需要在两端进行端口转发的问题,并解决多个客户端在一个 NAT 地址后面的问题。
-
好的,谢谢。是的,这是有道理的;我可以在 TcpClients 连接时存储它们。这至少解决了这部分问题
标签: vb.net sockets networking tcp portforwarding