连接互联网网络上的套接字失败。

6

目录

  • 前言
  • 服务器端代码
  • 客户端代码
  • 本地计算机示例(成功)
  • 互联网网络示例(失败)
  • 我的可能性考虑

前言

我从MSDN的类库示例中获取这些代码。所以它必须可以正常工作。是的,我部分正确。在我的计算机上运行时成功的。但是通过互联网网络,它失败了。每次我都会收到ConnectionRefusedSocketErrorCode
以下是源代码,首先,您必须知道我的修改测试。

对于服务器代码:

  • 我使用IPAddress.IPv6Any而不是IPAddress.Any
  • 也尝试了不使用server.AllowNatTraversal(true)

但它失败了

服务器端代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;

namespace ServerTest
{
    class Program
    {
        static void Main(string[] args)
        {
            TcpListener server = null;
            try
            {
                int port = 13000;
                server = new TcpListener(IPAddress.Any, port);
                server.AllowNatTraversal(true);
                server.Start();
                byte[] bytes = new byte[256];
                string data = null;
                while (true)
                {
                    Console.WriteLine("Waiting for a connection...");
                    TcpClient client = server.AcceptTcpClient();
                    Console.WriteLine("Connected: {0}", client.Client.LocalEndPoint.ToString());
                    data = null;
                    NetworkStream stream = client.GetStream();
                    int i;
                    while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
                    {
                        data = Encoding.ASCII.GetString(bytes, 0, i);
                        Console.WriteLine("Received: {0}", data);
                        data = data.ToUpper();
                        byte[] msg = Encoding.ASCII.GetBytes(data);
                        stream.Write(msg, 0, msg.Length);
                        Console.WriteLine("Sent: {0}", data);
                    }
                    client.Close();
                }
            }
            catch (SocketException e)
            {
                Console.WriteLine("Socket exception message: {0}", e.Message);
                Console.WriteLine("Socket Error Code: {0}", e.SocketErrorCode.ToString());
            }
            finally
            {
                server.Stop();
            }
            Console.WriteLine("\nHit enter to continue...");
            Console.ReadKey();            
        }
    }
}

客户端代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace ClientTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Started...");
            Console.WriteLine("İP Address:");
            string hostName = Console.ReadLine();
            if(hostName.Length == 0)
            {
                hostName = Dns.GetHostName();
            }
            Connect(hostName, "hello");
        }

        static void Connect(string server, string message)
        {
            try
            {
                int port = 13000;
                TcpClient client = new TcpClient(server, port);
                byte[] data = Encoding.ASCII.GetBytes(message);
                NetworkStream stream = client.GetStream();
                stream.Write(data, 0, data.Length);
                Console.WriteLine("Sent: {0}", message);
                data = new byte[256];
                string responseData = string.Empty;
                int bytes = stream.Read(data, 0, data.Length);
                responseData = Encoding.ASCII.GetString(data, 0, bytes);
                Console.WriteLine("Received: {0}", responseData);
                stream.Close();
                client.Close();
            }
            catch (ArgumentNullException e)
            {
                Console.WriteLine("ArgumentNullException: {0}", e.Message);
            }
            catch (SocketException e)
            {
                Console.WriteLine("Socket Error Code: {0}", e.SocketErrorCode.ToString());
            }
            Console.WriteLine("Hit enter to continue...");
            Console.ReadKey();
        }
    }
}

本地计算机示例(成功

我只在我的计算机上尝试过。首先我打开了ServerTest程序,然后运行了ClientText程序。

客户端输出

已启动...
IP地址:

发送hello
已接收HELLO
按回车键继续

服务器端输出

正在等待连接...
已连接:192.168.1.3:13000
已接收:hello
已发送:HELLO
正在等待连接

互联网网络示例(失败

我尝试与IP地址为“88.226.0.218”的朋友一起使用。他从whatismyipaddress.com了解了他的IP地址。我运行了ClientTest程序,他运行了ServerTest程序。以下是输出:

客户端输出

已启动...
IP地址:
88.226.0.218
SocketErrorCode:ConnectionRefused
按回车键继续

服务器端输出

正在等待连接...

什么也没有发生。ServerTest程序只是在等待。

我的可能性考虑

  • 当我使用IPAddress.IPv6Any时,它可能仅使用IPv6。
  • 我的调制解调器防火墙可能会阻止NatTraversal。如果是这样,我如何以编程方式启用调制解调器的NatTraversal?
  • TcpListener类的AllowNatTraversal方法随着.Net4一起提供,但无法正常工作。(我不相信,但为了可能性)

任何帮助将不胜感激。这对我非常重要。由于无法成功地解决此问题,我已经推迟了我的项目近一个月。


您肯定需要配置防火墙,将到达公共端口的流量传递到工作站上的相应端口。您的朋友可能会看到“连接被拒绝”的消息,因为...您的防火墙正在拒绝传递到该端口号的数据包,这是它的工作。如何操作取决于您使用的具体防火墙。 - Christopher
如果我们必须手动配置调制解调器NAT,我更喜欢使用已经在使用中的转发端口。是否有可用的已转发端口? - Mesut
当你说你更喜欢使用已经在使用中的转发端口时,我不确定我理解你的意思。在你的计算机上,你将无法将你的程序绑定到另一个服务已经使用的端口号;在防火墙上,你将无法将公共接口上的端口翻译成内部多个端口。虽然你的防火墙应该能够将外部的任意端口号转换为内部的任意端口号,1:1,但它不会变成1::1。 - Christopher
1个回答

0

有一件事可以尝试,就是在同一网络上的两台计算机之间进行测试。如果这样可以正常工作,那么你就可以将注意力从你自己的计算机问题上移开了。

无论如何,罪魁祸首很可能是防火墙,正如Christopher所说。实际上,在检查你自己的防火墙之前,我会先检查你朋友的防火墙,因为一些(大多数?)防火墙不会阻碍出站连接。

此外,如果你的朋友在路由器后面,你需要让他将端口13000转发到他计算机的本地地址(很可能是192.168.1.x)的13000端口。

更多关于防火墙和端口转发的信息(和指南!)可以在这里找到:http://portforward.com/help/start_here.htm


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接