Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何获取TcpListener的公共端口号?_C#_Sockets_Network Programming_Tcpclient_Tcplistener - Fatal编程技术网

C# 如何获取TcpListener的公共端口号?

C# 如何获取TcpListener的公共端口号?,c#,sockets,network-programming,tcpclient,tcplistener,C#,Sockets,Network Programming,Tcpclient,Tcplistener,我正在尝试直接连接(使用TCP)路由器后面实现NAT的两个设备。如我所见,路由器正在转换我设备的端口号,因此我计算机上的端口13000(我的应用程序正在侦听传入TCP连接的端口)将具有与公开看到的完全不同的值。为了连接两个设备,我需要知道侦听器的“公共端口号”是什么 我已经创建了公开的“会合服务器”。首先,我在客户端A和服务器之间创建了TCP连接。服务器提取端口号并将其传递给其他客户端,以便它们可以尝试连接到客户端A。但我意识到,当我与服务器创建新的Tcp连接时,我的应用程序会创建新的端口,从中

我正在尝试直接连接(使用TCP)路由器后面实现NAT的两个设备。如我所见,路由器正在转换我设备的端口号,因此我计算机上的端口13000(我的应用程序正在侦听传入TCP连接的端口)将具有与公开看到的完全不同的值。为了连接两个设备,我需要知道侦听器的“公共端口号”是什么

我已经创建了公开的“会合服务器”。首先,我在客户端A和服务器之间创建了TCP连接。服务器提取端口号并将其传递给其他客户端,以便它们可以尝试连接到客户端A。但我意识到,当我与服务器创建新的Tcp连接时,我的应用程序会创建新的端口,从中发送数据包。所以服务器提取新创建的端口的公共端口,该端口仅用于连接到该服务器,而不是侦听器的公共端口

所以我试着用另一种方法来解决它。其思想是:我正在发送源端口设置为TcpListener端口的UDP数据包。这样,理论上,服务器可以从TcpListener的传入消息公共端口提取(通过从UDP数据报获取源端口),并将其传递给网络中的其他设备

// client side
public void AdvertiseListener(IPAddress address, int port, Guid localDeviceId)
{
    UdpClient client = new UdpClient(ListenerPort); // changing datagram source to port of my TcpListener
    IPEndPoint remoteEP = new IPEndPoint(address, port);

    _logger.LogInformation($"Advertising Tcp port to server at {address.MapToIPv4().ToString()}:{port}");

    byte[] data = localDeviceId.ToByteArray();
    for (int a = 0; a < 10; a++)
    {
        client.Send(data, data.Length, remoteEP);
    }
}


// server side
public void AdvertisementsHandler()
{
    AdvertisementListener = new UdpClient(ListenerPort);

    AdvertisementListener.BeginReceive(new AsyncCallback(HandleAdverticement), null);
}


private void HandleAdverticement(IAsyncResult ar)
{
    IPEndPoint senderIpEndPoint = new IPEndPoint(0, 0); // source address of incoming datagram
    var receivedData = AdvertisementListener.EndReceive(ar, ref senderIpEndPoint);

    [...]

    _logger.LogInformation($"ADVERTICEMENT RECEIVED, port is {senderIpEndPoint.Port}");

    try
    {
        AdvertisementListener.BeginReceive(new AsyncCallback(HandleAdverticement), null);
    }
    catch (Exception e)
    {
        _logger.LogError("Advertiser failed");
    }

}
//客户端
public void AdvertiseListener(IPAddress地址、int端口、Guid localDeviceId)
{
UdpClient client=新的UdpClient(ListenerPort);//将数据报源更改为我的TcpListener的端口
IPEndPoint remoteEP=新IPEndPoint(地址、端口);
_logger.LogInformation($“在{address.maptopv4().ToString()}:{port}向服务器公布Tcp端口”);
byte[]data=localDeviceId.ToByteArray();
对于(int a=0;a<10;a++)
{
client.Send(数据、数据、长度、remoteEP);
}
}
//服务器端
公共无效广告Shandler()
{
AdvertisementListener=新的UdpClient(ListenerPort);
BeginReceive(新的AsyncCallback(HandleAdverticement),null);
}
专用无效手动引线水泥(IAsyncResult ar)
{
IPEndPoint senderIpEndPoint=新IPEndPoint(0,0);//传入数据报的源地址
var receivedData=AdvertisementListener.EndReceive(ar,ref senderIpEndPoint);
[...]
_logger.LogInformation($“收到通知,端口为{senderIpEndPoint.port}”);
尝试
{
BeginReceive(新的AsyncCallback(HandleAdverticement),null);
}
捕获(例外e)
{
_logger.LogError(“广告客户失败”);
}
}

问题是:由于某种原因,我的服务器接收到的数字没有翻译
senderIpEndPoint
HandleAdverticement
中等于13000,这是我的专用端口号。具有讽刺意味的是,我的路由器似乎这次就这样离开了端口。你知道我可以改变什么来解决我的问题吗?

你有什么理由不能在路由器上使用端口转发吗?@PatrickMcvay是的,我希望我的应用程序在我无法访问路由器设置的网络上工作。我肯定你已经想到了这一点,但你是否尝试过使用套接字而不是UdpClient?文档您不能在路由器上使用端口转发有什么原因吗?@PatrickMcvay是的,我希望我的应用程序能够在无法访问路由器设置的网络上工作。我相信您已经想到了这一点,但您是否尝试过使用套接字而不是UdpClient?文档