C# 如何获取TcpListener的公共端口号?
我正在尝试直接连接(使用TCP)路由器后面实现NAT的两个设备。如我所见,路由器正在转换我设备的端口号,因此我计算机上的端口13000(我的应用程序正在侦听传入TCP连接的端口)将具有与公开看到的完全不同的值。为了连接两个设备,我需要知道侦听器的“公共端口号”是什么 我已经创建了公开的“会合服务器”。首先,我在客户端A和服务器之间创建了TCP连接。服务器提取端口号并将其传递给其他客户端,以便它们可以尝试连接到客户端A。但我意识到,当我与服务器创建新的Tcp连接时,我的应用程序会创建新的端口,从中发送数据包。所以服务器提取新创建的端口的公共端口,该端口仅用于连接到该服务器,而不是侦听器的公共端口 所以我试着用另一种方法来解决它。其思想是:我正在发送源端口设置为TcpListener端口的UDP数据包。这样,理论上,服务器可以从TcpListener的传入消息公共端口提取(通过从UDP数据报获取源端口),并将其传递给网络中的其他设备C# 如何获取TcpListener的公共端口号?,c#,sockets,network-programming,tcpclient,tcplistener,C#,Sockets,Network Programming,Tcpclient,Tcplistener,我正在尝试直接连接(使用TCP)路由器后面实现NAT的两个设备。如我所见,路由器正在转换我设备的端口号,因此我计算机上的端口13000(我的应用程序正在侦听传入TCP连接的端口)将具有与公开看到的完全不同的值。为了连接两个设备,我需要知道侦听器的“公共端口号”是什么 我已经创建了公开的“会合服务器”。首先,我在客户端A和服务器之间创建了TCP连接。服务器提取端口号并将其传递给其他客户端,以便它们可以尝试连接到客户端A。但我意识到,当我与服务器创建新的Tcp连接时,我的应用程序会创建新的端口,从中
// 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?文档