【问题标题】:C# Public IP Client/ServerC# 公共 IP 客户端/服务器
【发布时间】:2018-04-01 07:30:44
【问题描述】:

出于学习目的,我开发了一个在本地网络上运行的异步服务器/客户端应用程序。但现在我想让它能够连接到我的公共 IP,这样我的服务器就可以从任何地方访问。

这是服务器代码的相关部分,它似乎工作得很好:

    static void Main(string[] args)
    {
            AsyncServer server = new AsyncServer(60101);
            server.RunAsync();
            Console.Read();
    }

public class AsyncServer
{
    private IPAddress ipAddress;
    private int port;

    public AsyncServer(int port)
    {
        this.port = port;
        IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
        this.ipAddress = null;
        for (int i = 0; i < ipHostInfo.AddressList.Length; i++)
        {
            if (ipHostInfo.AddressList[i].AddressFamily == AddressFamily.InterNetwork)
            {
                this.ipAddress = ipHostInfo.AddressList[i];
                break;
            }
        }
        if (this.ipAddress == null)
            throw new Exception("No IPv4 address for server.");
    }

    public async void RunAsync()
    {
        TcpListener tcpListener = new TcpListener(this.ipAddress, this.port);
        tcpListener.Start();

这里是客户端代码的相关部分。这是连接失败的地方。

    static void Main(string[] args)
    {
            AsyncClient client = new AsyncClient("MyPublicIP", 60101);
            client.ConnectAsync().Wait();
            Console.Read();
    }
}

public class AsyncClient
{
    private IPAddress ipAddress;
    private int port;

    public AsyncClient(string ip, int port)
    {
        this.port = port;
        IPAddress.TryParse(ip, out ipAddress);
    }

    public async Task ConnectAsync()
    {
        int attempts = 0;
        TcpClient client = new TcpClient();
        while (!client.Connected)
        {
            try
            {
                attempts++;
                client.Connect(this.ipAddress, this.port);
                Console.Clear();
                Console.WriteLine("Connected");
                await ProcessAssync(client);
            }
            catch (SocketException)
            {
                Console.Clear();
                Console.WriteLine("Connection Attempts: {0}", attempts);

我已经在我的路由器上将端口转发到我的本地服务器 IP“192.168.254.1”到使用的端口“60101”,但没有任何变化,他只是在那里尝试了一段时间然后连接失败。

【问题讨论】:

  • 他不会连接到 192.168.254.1 .. 他需要你的本地 IP 地址
  • 是的,192.168.254.1 是我的本地 IP,但这是我需要的服务器,对吧?因此,服务器会在给定端口上侦听发送到该 IP 的所有内容,就像我在端口转发上设置的一样。然后在客户端我没有尝试连接到它,它正在尝试连接到我的公共 IP。这不应该是这样吗?
  • 是的,这听起来很正确。所以问题可能是 ISP 过滤或转发不起作用或其他问题。
  • 检查您的防火墙是否配置为允许通信通过...
  • 您的问题中有很多不相关的代码。阅读How to Ask 并创建一个minimal reproducible example。您可能绑定到错误的地址。您绝对不能绑定到您的公共 IP 地址,因为它分配给您的路由器,而不是您的 PC(假设您是典型的家用路由器)。

标签: c# sockets ipv4


【解决方案1】:

您真的想要/需要限制服务器仅在一个接口上侦听吗?

当您仅使用端口号而不使用 IP 地址启动 TcpListener 时,TcpListener 将侦听所有接口。使用您的代码,TcpListener 将仅在具有 IPv4 IP 地址的第一个接口上侦听。但这可能是您的路由器无法使用的接口(例如,虚拟主机提供的内部接口)。

我会将服务器代码更改为这样的:

public class AsyncServer
{
    private int port;

    public AsyncServer(int port)
    {
        this.port = port;
    }

    public async void RunAsync()
    {
        TcpListener tcpListener = new TcpListener(IPAddress.Any, this.port);
        tcpListener.Start();

【讨论】:

    【解决方案2】:

    尝试http://www.whatsmyip.org/ 并解析该 IP。对于服务器,使用 IPAddress.Any 可能会更好

    【讨论】:

    • 一般来说,在 NAT 之后(这很常见),您的公共 IP 分配给您的调制解调器/路由器,而不是您的 PC。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-25
    • 1970-01-01
    • 2016-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-13
    相关资源
    最近更新 更多