TcpClient未连接到远程服务器

我正在尝试使用TcpClient类连接到远程计算机,但它仍然失败:

System.dll中出现未处理的“System.Net.Sockets.SocketException”类型exception

附加信息:连接尝试失败,因为连接方在一段时间后没有正确响应,或者建立的连接失败,因为连接的主机无法响应

在客户端和服务器本地工作时测试代码,但是当我尝试连接到远程计算机时,它不再起作用。

这是服务器代码:

using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Net.WebSockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace WebSocketServer { class Program { static void Main(string[] args) { Console.WriteLine("Starting a new WebSockets server."); WebSocketServer server = new WebSocketServer(); Console.WriteLine("The WebSocket server has started."); bool userRequestedShutdown = false; while (!userRequestedShutdown) { Console.ReadLine(); DialogResult result = MessageBox.Show("Do you want to shut the server down?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (result == DialogResult.Yes) { userRequestedShutdown = true; } } server.Stop(); } class WebSocketServer { TcpListener server; Thread connectionListener; ConcurrentDictionary clients = new ConcurrentDictionary(); public WebSocketServer() { server = new TcpListener(IPAddress.Parse("127.0.0.1"), (int)Properties.Settings.Default["Port"]); try { server.Start(); } catch (Exception exception) { Console.WriteLine("Error while trying to start the server: {0}", exception.ToString()); } connectionListener = new Thread(() => { while (true) { Console.WriteLine("Waiting for a new client."); try { TcpClient client = server.AcceptTcpClient(); Thread clientListener = new Thread(() => { try { NetworkStream stream = client.GetStream(); byte[] buffer = new byte[1024]; Console.WriteLine("Wating for the client to write."); while (client.Connected) { try { int bytesRead = stream.Read(buffer, 0, buffer.Length); Console.WriteLine("Read {0} bytes from the client.", bytesRead); string data = Encoding.UTF8.GetString(buffer).Substring(0, bytesRead); Console.WriteLine("Read the following string from the client: {0}", data); } catch (Exception exception) { Console.WriteLine("Error while trying to read from a TCP client: {0}", exception.ToString()); break; } } Console.WriteLine("Client disconnected. Removing client."); } catch (Exception exception) { Console.WriteLine("Error while trying to connect to a TCP client: {0}", exception.ToString()); } client.Close(); clients.TryRemove(client, out clientListener); }); clientListener.Start(); clients.TryAdd(client, clientListener); } catch (Exception exception) { Console.WriteLine("Error while trying to accept a TCP client: {0}", exception.ToString()); } Console.WriteLine("A client has connected."); } }); connectionListener.Start(); } public void Stop() { server.Stop(); connectionListener.Abort(); } } } } 

这是客户端代码:

 using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; namespace WebSocketClient { class Program { static void Main(string[] args) { Console.WriteLine("Opening up a TcpClient."); TcpClient client = new TcpClient(); client.Connect("", ); Console.WriteLine("TcpClient has connected."); NetworkStream stream = client.GetStream(); bool closed = false; new Thread(() => { while (!closed) { Console.WriteLine("Writing data to the stream."); byte[] bytes = Encoding.UTF8.GetBytes("Hello, world."); stream.Write(bytes, 0, bytes.Length); Thread.Sleep(1000); } }).Start(); Console.ReadLine(); closed = true; } } } 

那么这里的问题是什么? 我在Azure虚拟机上托管服务器,我通过设置入站和出站规则打开了我尝试在远程服务器上的Windows防火墙中用作的TCP端口,以允许所有流量进出该端口上的机器,我在Azure门户上创建了一个TCP端点,它将我的虚拟机主机名的外部端口映射到我的虚拟机的内部专用端口,两者都设置为映射相同的端口号为了一致性。 要进行连接,我使用的是.cloudapp.net 。 我也尝试使用IPAddress.Parse()连接流IPAddress.Parse()但没有运气…它只是保持超时,好像我没有正确格式化主机名或其他东西。 我错过了什么? 如果有人能提供一些关于如何调试问题的线索,那也会非常有帮助。

更新 :运行WireShark跟踪,我看到很多这些消息(这是不是很糟糕?我认为如果考虑到对于Azure,您必须将数据包从公共域的端口路由到私有端口,TCP重传可能没问题。 VM,但不确定RST,ACK是什么):

在此处输入图像描述

更新 :运行Microsoft Message Analyzer,我在本地链接层上看到这些消息:

在此处输入图像描述

注意:我的VM的内部IP为100.75.20.78,公共IP为191.238.37.130。 它的公共域名是ovidius.cloudapp.net。 我试图在TCP端口6490上托管应用程序。为了不放弃,我将我的个人IP地址涂黑了。

我已将Azure门户中的TCP端口从域映射到VM,如下所示:

在此处输入图像描述

在花了两个母亲_______天之后(填空),我在探索替代方法方面有点创新,试着看看我是否可以规范路由问题。 我可以非常安全地得出结论,当您将公共端口映射到同一个私有端口时,Microsoft的虚拟机路由会失败。

例如,我尝试在下面设置新的Socket端点,它起作用,因为它没有像我之前使用WebSocketServer那样将相同的域端口映射到同一个虚拟机端口:

在此处输入图像描述

更新 :此外,托管时,我必须设置服务器,而不是IP 127.0.0.1,但内部IP,在我的情况下是100.75.20.78。

再次更新 :与上述解决方案相反,我尝试在6490删除旧端点并重新创建它,当我现在连接到该地址时,它似乎正在工作。 我不完全确定为什么,我只能说这里唯一的区别就是我在这次创建端点之前有防火墙规则允许该端点的端口……不确定这是否会产生影响。 老实说,我不确定是什么导致了这些问题。

再次更新考虑一下……我认为它归结为以下两个问题:

  1. 您需要在Azure虚拟机的内部IP上托管服务器,而不是像我当前那样托管本地主机或127.0.0.1。
  2. 您需要在Azure端点上未启用“ENABLE DIRECT SERVER RETURN”function。