【问题标题】:Cannot connect to another computer over TCP无法通过 TCP 连接到另一台计算机
【发布时间】:2019-07-18 18:17:02
【问题描述】:

我正在做一个通过 TCP 传输文件的项目。它是用 .NET 4.7 编写的。该程序在客户端连接到同一台计算机上的服务器时运行,但是当我将它发送给朋友并尝试连接它时,我收到错误:

连接尝试失败,因为连接方在一段时间后没有正确响应,或者连接失败,因为连接的主机没有响应

目前该程序仅发送有关将被复制的文件的一些信息,并且没有任何加密,因为我什至无法发送这些信息。

这是服务器的代码(使用 Invoke 是因为它在单独的线程上运行):

    private void Server_Start()
    {


        try
        {
            // Set port on 13000
            int port = 13000;

            //Get the ip adress for the server
            String localIp;

            using (var client = new WebClient())
            {
                // Try connecting to Google public DNS and get the local endpoint as IP
                // If failed to connect set IP as local IP
                if (CheckForInternetConnection())
                {
                    try
                    {
                        using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
                        {
                            socket.Connect("8.8.8.8", 65530);
                            IPEndPoint endPoint = socket.LocalEndPoint as IPEndPoint;
                            localIp = endPoint.Address.ToString();
                        }
                    }
                    catch (Exception e)
                    {
                        localIp = "127.0.0.1";
                    }
                }
                else
                {
                    localIp = "127.0.0.1";
                }
            }


            IPAddress IP = IPAddress.Parse(localIp);

            // Create listener and start listening 
            server = new TcpListener(IP, port);
            server.Start();

            // Buffer for data
            Byte[] bytes = new byte[256];
            String data = string.Empty;
            this.Invoke((MethodInvoker)(() => Log.Items.Add("Server started on ip: " + IP.ToString())));
            while (true)
            {

                // Accepting requests
                TcpClient client = server.AcceptTcpClient();

                // Get the stream object
                NetworkStream stream = client.GetStream();

                // Read length of file name
                byte[] nameLength = new byte[4];
                stream.Read(nameLength, 0, 4);
                int nameSize = BitConverter.ToInt32(nameLength, 0);

                // Read the name of file
                byte[] name = new byte[nameSize];
                stream.Read(name, 0, nameSize);
                String fileName = Encoding.UTF8.GetString(name);

                // Read size of file
                byte[] fileSizeB = new byte[4];
                stream.Read(fileSizeB, 0, 4);
                int fileSize = BitConverter.ToInt32(fileSizeB, 0);

                // Read start signal
                byte[] startB = new byte[9+1];
                stream.Read(startB, 0, 9);
                String start = Encoding.UTF8.GetString(startB);

                this.Invoke((MethodInvoker)(() => Log.Items.Add("Size of name: " + nameSize.ToString())));
                this.Invoke((MethodInvoker)(() => Log.Items.Add("Name of file: " + fileName)));
                this.Invoke((MethodInvoker)(() => Log.Items.Add("File size: " + fileSize.ToString())));
                this.Invoke((MethodInvoker)(() => Log.Items.Add("Start signal: " + start)));

                // Response to client
                byte[] message = Encoding.UTF8.GetBytes("Testmessage");
                stream.Write(message, 0, message.Length);
            }
            server.Stop();
            Log.Items.Add("Server started on ip: " + IP.ToString());
        }
        catch (Exception e)
        {
            this.Invoke((MethodInvoker)(() => Log.Items.Add(e)));
        }

    }

这是客户端的代码:

    private void button1_Click(object sender, EventArgs e)
    {
        IPAddress iP = IPAddress.Parse(ConnectIp.Text);
        int port = 13000;
        int buffersize = 1024;

        TcpClient client = new TcpClient();
        NetworkStream netStream;

        // Try to connect to server
        try
        {
            client.Connect(new IPEndPoint(iP, port));
        }
        catch(Exception ex)
        {
            this.Invoke((MethodInvoker)(() => Log.Items.Add(ex.Message)));
            return;
        }

        netStream = client.GetStream();

        String path = "D:\\testingEnv\\test1\\testing\\Matematika\\2017\\Školsko\\2017-SS-skolsko-B-1234-zad.pdf";

        String Filename = Path.GetFileName(path);

        // We wish to send some data in advance:
        // File name, file size, number of packets, send start and send end

        byte[] data = File.ReadAllBytes(path);

        // First packet contains: name size, file name, file size and "sendStart" signal
        byte[] nameSize = BitConverter.GetBytes(Encoding.UTF8.GetByteCount(Filename)); // Int
        byte[] nameB = Encoding.UTF8.GetBytes(Filename);
        byte[] fileSize = BitConverter.GetBytes(data.Length);
        byte[] start = Encoding.UTF8.GetBytes("sendStart");

        // Last packet constains: "sendEnd" signal to stop reading netStream
        byte[] end = Encoding.UTF8.GetBytes("sendEnd");

        // Creating the first package: nameSize, fileName, fileSize and start signal
        byte[] FirstPackage = new byte[4 + nameB.Length + 4 + 9];
        nameSize.CopyTo(FirstPackage, 0);
        nameB.CopyTo(FirstPackage, 4);
        fileSize.CopyTo(FirstPackage, 4 + nameB.Length);
        start.CopyTo(FirstPackage, 4 + nameB.Length + 4);

        // Send the first pckage
        netStream.Write(FirstPackage, 0, FirstPackage.Length);

        byte[] buffer = new byte[30];

        // Read the response
        netStream.Read(buffer, 0, 11);

        netStream.Close();



        client.Close();
    }

一位朋友尝试将端口转发到 13000,但也没有成功。我们甚至尝试关闭防火墙但没有。我在互联网上搜索,但找不到任何解决问题的方法。

需要注意的一点是,这两个函数都在同一个应用程序中。我不知道这是否是问题的原因。

有人知道这是怎么回事吗?

提前致谢

【问题讨论】:

  • 您在创建TcpListener 时是否确保localIp 不是127.0.0.1
  • 我假设您已经检查过您的服务器使用的 IP 不是 127.0.0.1... 然后确保该端口是真正打开的。尝试在服务器运行时使用 telnet 或 Putty 从外部连接到该主机:端口。
  • 服务器的 IP 被写在应用程序中,所以我确定它不是 localhost。端口是打开的,telnet 不会连接到它。正如我在下面的评论中提到的,它确实连接到我在网络上的计算机(不同的 IP)。

标签: c# .net tcp tcpclient tcplistener


【解决方案1】:

您是否尝试过使用 telnet 连接到您的服务器? “telnet localhost 13000”或来自其他具有正确 ip 和地址 nbr 的计算机?在调试服务器代码时尝试一下。如果 telnet 可以工作,那么客户端代码有问题..

【讨论】:

  • 我试过了,但它无法连接到另一台计算机。它连接到本地网络(不是本地主机,而是我的笔记本电脑所在的主机)。如果我在另一个 IP 上连接到我的计算机,该 IP 连接到同一个路由器但使用有线连接,则该应用程序可以工作。客户端代码会有什么问题?
  • 好的,有了这些信息,我认为问题不在于代码本身。似乎是与网络相关的问题。它在本地和同一个本地网络中工作。您可以尝试检查您的朋友 IP(服务器代码在启动后使用的 IP)是否在您的机器上可见。您可以在命令提示符窗口中使用 ping 和 tracert 命令进行故障排除。
  • 使用他的IP时ping和tracert都超时。他发现他的路由器不响应 ICMP 协议但 tracert 连接。我们已经尝试了私有和公共 IP 地址,但是当我在程序中使用公共 IP 来启动监听器时,它会抛出一个异常,说“请求的地址在其上下文中无效”。
  • 他发现 ping 请求到达了他的路由器,只是没有响应。
  • 好的。我认为防火墙可能仍然存在问题。要使 ping 命令正常工作,防火墙应允许 ICMP 协议。您也可以尝试以另一种方式进行测试,您的机器是服务器,而您的朋友尝试从他的机器连接...也许防火墙允许更好的出站连接
猜你喜欢
  • 1970-01-01
  • 2018-12-11
  • 2017-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-19
相关资源
最近更新 更多