我试图用套接字选项作为重用地址来完成Tcp打孔 .

  • 第一步 - 使用活动打开的tcp端口8001在服务器 S 中运行和tcp监听器 .

  • 第二步 - 在客户端 A 上的套接字选项中运行带有重用地址的Tcp套接字(方法名称为 enableReuseAddres(Socket sck) ,如下所示),该套接字在端口8001上的NAT后面 .

  • 第三步 - 连接 A => S .

  • 第四步 - 从 A => S 发送数据,并从 S => A 获取确认数据 .

  • 第五步 - 获取 A 的远程 endpoints ,即X.X.X.X:8001(外部IP和 A 的端口) .

  • 第六步 - 使用端口8001(方法名称为 runServer ,如下所述),在客户端 A 中侦听套接字选项中的重用地址(方法名称为 enableReuseAddres(Socket sck) ,如下所述) . 免责声明: - 没有发现错误,并且能够在ReuseAddress的帮助下绑定用于连接服务器 S 的相同 endpoints ,并且能够侦听同一端口8001.但是当我尝试检查端口8001是打开还是关闭时客户端 A 我总是关闭端口 .

public void runServer()
    {

        Socket sk = new Socket(AddressFamily.InterNetwork, 
        SocketType.Stream, ProtocolType.Tcp);
        enableReuseAddres(sk);
        sk.Bind(loclEP);
        sk.Listen(1);
        var connection_socket = sk.Accept();
        MessageBox.Show("Connected");

    }
    IPEndPoint loclEP = new IPEndPoint(IPAddress.Any, 8001);
    public void enableReuseAddres(Socket sck)
    {
         sck.SetSocketOption(SocketOptionLevel.Socket, 
         SocketOptionName.ReuseAddress, true);
         sck.SetSocketOption(SocketOptionLevel.Socket, 
         SocketOptionName.KeepAlive, true);
    }