簡體   English   中英

TcpClient未連接到遠程服務器

[英]TcpClient not connecting to remote server

我正在嘗試使用TcpClient類連接到遠程計算機,但它仍然失敗:

System.dll中出現未處理的“System.Net.Sockets.SocketException”類型異常

附加信息:連接嘗試失敗,因為連接方在一段時間后沒有正確響應,或者建立的連接失敗,因為連接的主機無法響應

在客戶端和服務器本地工作時測試代碼,但是當我嘗試連接到遠程計算機時,它不再起作用。

這是服務器代碼:

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<TcpClient, Thread> clients = new ConcurrentDictionary<TcpClient, Thread>();

            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("<Remote Hostname>", <RemotePortNumber>);
            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防火牆中用作<RemotePortNumber>的TCP端口,以允許所有流量進出該端口上的機器,我在Azure門戶上創建了一個TCP端點,它將我的虛擬機主機名的外部端口映射到我的虛擬機的內部專用端口,兩者都設置為映射相同的端口號<RemotePortNumber>為了一致性。 要連接,我使用的是<Remote Hostname><MyServiceName>.cloudapp.net 我還嘗試使用IPAddress.Parse(<Public IP of my Azure Server>)連接流,但沒有運氣......它只是保持超時,好像我沒有正確格式化主機名或其他東西。 我錯過了什么? 如果有人能提供一些關於如何調試問題的線索,那也會非常有幫助。

更新 :運行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”功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM