UDP端口打孔C#
我试图让NAT后面的两个客户端使用端口转发工作的服务器相互通信,我的场景:UDP端口打孔C#,udp,hole-punching,Udp,Hole Punching,我试图让NAT后面的两个客户端使用端口转发工作的服务器相互通信,我的场景: Server start listering on port 45000 for Client_A connection; Server Start listering on port 45001 for Client_B connection; Client_A connect to server on port 45000 and send hello message; Client_B connect to
Server start listering on port 45000 for Client_A connection;
Server Start listering on port 45001 for Client_B connection;
Client_A connect to server on port 45000 and send hello message;
Client_B connect to server on port 45001 and send hello message;
Server Receive hello message from Client_B and send message with Client_B external port (ex 56000) to Client_B;
Client_B receive external port and start listering on port 56000;
Server Receive hello message from Client_A and send message with Client_B IP and port to Client_A;
Client_A receive IP and Port of Client_B;
Client_A connect to Client_B and send hello message
问题:
Client_B does not receive message from Client_A;
static int server_A_Port = 45000;
static int server_B_Port = 45001;
static UdpClient server_A;
static UdpClient server_B;
static bool client_B_Connected = false;
static string client_A_Ip = "";
static string client_B_Ip = "";
static int client_A_Port = 0;
static int client_B_Port = 0;
static Thread Server_A_Thread = new Thread(Start_Server_A);
static Thread Server_B_Thread = new Thread(Start_Server_B);
static void Main(string[] args)
{
Server_A_Thread.Start();
Server_B_Thread.Start();
}
static void Start_Server_A()
{
Console.WriteLine("Starting Server_A on port: " + server_A_Port);
server_A = new UdpClient();
IPEndPoint client_A_IpEp = new IPEndPoint(IPAddress.Any, server_A_Port);
server_A.Client.Bind(client_A_IpEp);
Console.WriteLine("Server Started. Waiting Client_A Message");
string c_a = "";
while (string.IsNullOrEmpty(c_a))
{
try
{
c_a = ReceiveMessageFromClient(server_A, ref client_A_IpEp);
Console.WriteLine("Message received from Client_A: " + c_a);
client_A_Ip = ((IPEndPoint)client_A_IpEp).Address.ToString();
client_A_Port = ((IPEndPoint)client_A_IpEp).Port;
server_A.Connect(client_A_IpEp);
}
catch(Exception err)
{
Thread.Sleep(1000);
}
}
Console.WriteLine("Waiting Client_B connection");
bool sended = false;
while (!sended)
{
if(client_B_Connected)
{
Console.WriteLine("Client_B connected, sending Client_B IP and Port to Client_A");
SendMessageToClient(server_A, client_B_Ip + ":" + client_B_Port);
sended = true;
Console.WriteLine("Message Sended to Client_A");
break;
}
Thread.Sleep(1000);
}
Console.ReadLine();
}
static void Start_Server_B()
{
Console.WriteLine("Starting Server_B on port: " + server_B_Port);
server_B = new UdpClient();
IPEndPoint client_B_IpEp = new IPEndPoint(IPAddress.Any, server_B_Port);
server_B.Client.Bind(client_B_IpEp);
Console.WriteLine("Server Started. Waiting Client_B Message");
string c_b = "";
while (string.IsNullOrEmpty(c_b))
{
try
{
c_b = ReceiveMessageFromClient(server_B, ref client_B_IpEp);
Console.WriteLine("Message received from Client_B: " + c_b);
client_B_Ip = ((IPEndPoint)client_B_IpEp).Address.ToString();
client_B_Port = ((IPEndPoint)client_B_IpEp).Port;
server_B.Connect(client_B_IpEp);
client_B_Connected = true;
}
catch (Exception err)
{
Thread.Sleep(1000);
}
}
Console.WriteLine("Sending external Port to Client_B start listering");
SendMessageToClient(server_B,client_B_Port + "");
}
static void SendMessageToClient(UdpClient client, string message)
{
byte[] data = Encoding.GetEncoding(28591).GetBytes(message);
client.Send(data, data.Length);
}
static string ReceiveMessageFromClient(UdpClient client, ref IPEndPoint ep)
{
byte[] data = client.Receive(ref ep);
string receivedString = Encoding.GetEncoding(28591).GetString(data);
return receivedString;
}
代码如下:
服务器:
Client_B does not receive message from Client_A;
static int server_A_Port = 45000;
static int server_B_Port = 45001;
static UdpClient server_A;
static UdpClient server_B;
static bool client_B_Connected = false;
static string client_A_Ip = "";
static string client_B_Ip = "";
static int client_A_Port = 0;
static int client_B_Port = 0;
static Thread Server_A_Thread = new Thread(Start_Server_A);
static Thread Server_B_Thread = new Thread(Start_Server_B);
static void Main(string[] args)
{
Server_A_Thread.Start();
Server_B_Thread.Start();
}
static void Start_Server_A()
{
Console.WriteLine("Starting Server_A on port: " + server_A_Port);
server_A = new UdpClient();
IPEndPoint client_A_IpEp = new IPEndPoint(IPAddress.Any, server_A_Port);
server_A.Client.Bind(client_A_IpEp);
Console.WriteLine("Server Started. Waiting Client_A Message");
string c_a = "";
while (string.IsNullOrEmpty(c_a))
{
try
{
c_a = ReceiveMessageFromClient(server_A, ref client_A_IpEp);
Console.WriteLine("Message received from Client_A: " + c_a);
client_A_Ip = ((IPEndPoint)client_A_IpEp).Address.ToString();
client_A_Port = ((IPEndPoint)client_A_IpEp).Port;
server_A.Connect(client_A_IpEp);
}
catch(Exception err)
{
Thread.Sleep(1000);
}
}
Console.WriteLine("Waiting Client_B connection");
bool sended = false;
while (!sended)
{
if(client_B_Connected)
{
Console.WriteLine("Client_B connected, sending Client_B IP and Port to Client_A");
SendMessageToClient(server_A, client_B_Ip + ":" + client_B_Port);
sended = true;
Console.WriteLine("Message Sended to Client_A");
break;
}
Thread.Sleep(1000);
}
Console.ReadLine();
}
static void Start_Server_B()
{
Console.WriteLine("Starting Server_B on port: " + server_B_Port);
server_B = new UdpClient();
IPEndPoint client_B_IpEp = new IPEndPoint(IPAddress.Any, server_B_Port);
server_B.Client.Bind(client_B_IpEp);
Console.WriteLine("Server Started. Waiting Client_B Message");
string c_b = "";
while (string.IsNullOrEmpty(c_b))
{
try
{
c_b = ReceiveMessageFromClient(server_B, ref client_B_IpEp);
Console.WriteLine("Message received from Client_B: " + c_b);
client_B_Ip = ((IPEndPoint)client_B_IpEp).Address.ToString();
client_B_Port = ((IPEndPoint)client_B_IpEp).Port;
server_B.Connect(client_B_IpEp);
client_B_Connected = true;
}
catch (Exception err)
{
Thread.Sleep(1000);
}
}
Console.WriteLine("Sending external Port to Client_B start listering");
SendMessageToClient(server_B,client_B_Port + "");
}
static void SendMessageToClient(UdpClient client, string message)
{
byte[] data = Encoding.GetEncoding(28591).GetBytes(message);
client.Send(data, data.Length);
}
static string ReceiveMessageFromClient(UdpClient client, ref IPEndPoint ep)
{
byte[] data = client.Receive(ref ep);
string receivedString = Encoding.GetEncoding(28591).GetString(data);
return receivedString;
}
客户_A
static string serverIp = "X.X.X.X";
static int serverPort = 45000;
static string otherClientIp = "0.0.0.0";
static int otherClientPort = 0;
static UdpClient client = new UdpClient();
static void Main(string[] args)
{
Console.WriteLine("Connecting to server...");
client.Connect(serverIp, serverPort);
Console.WriteLine("Connected. Sending request message...");
SendMessageToServer();
Console.WriteLine("Sended. Waiting response...");
string s = "";
while (string.IsNullOrEmpty(s))
{
try
{
s = ReceiveMessageFromServer();
Console.WriteLine("Response received from server.");
}
catch (Exception err)
{
Thread.Sleep(1000);
}
}
string[] otherClientInfo = s.Split(':');
otherClientIp = otherClientInfo[0];
otherClientPort = int.Parse(otherClientInfo[1]);
Console.WriteLine("Other Client info: " + otherClientIp + ":" + otherClientPort);
Thread.Sleep(2000);
Console.WriteLine("Connecting to Client_B...");
client.Connect(otherClientIp, otherClientPort);
Console.WriteLine("Connected. Sending hello hessage...");
SendMessageToClient();
Console.WriteLine("Sended. Waiting response...");
string c = "";
while (string.IsNullOrEmpty(c))
{
try
{
IPEndPoint ep = (IPEndPoint)client.Client.RemoteEndPoint;
c = ReceiveMessageFromClient(client,ref ep);
Console.WriteLine("Response received from Client_B.");
Console.WriteLine("Response: " + c);
Console.ReadLine();
}
catch (Exception err)
{
Thread.Sleep(1000);
}
}
}
static void SendMessageToServer()
{
byte[] data = Encoding.GetEncoding(28591).GetBytes("FROM CLIENT TO SERVER");
client.Send(data, data.Length);
}
static void SendMessageToClient()
{
byte[] data = Encoding.GetEncoding(28591).GetBytes("FROM CLIENT_A TO CLIENT_B");
client.Send(data, data.Length);
}
static string ReceiveMessageFromServer()
{
IPEndPoint serverIpEp = new IPEndPoint(IPAddress.Parse(serverIp), serverPort);
byte[] data = client.Receive(ref serverIpEp);
string receivedString = Encoding.GetEncoding(28591).GetString(data);
return receivedString;
}
static string ReceiveMessageFromClient(UdpClient server, ref IPEndPoint ep)
{
byte[] data = server.Receive(ref ep);
string receivedString = Encoding.GetEncoding(28591).GetString(data);
return receivedString;
}
客户_B
static string serverIp = "X.X.X.X";
static int serverPort = 45001;
static UdpClient client = new UdpClient();
static void Main(string[] args)
{
Console.WriteLine("Connecting to server...");
client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
client.Connect(serverIp, serverPort);
Console.WriteLine("Connected. Sending request message...");
SendMessageToServer();
Console.WriteLine("Sended. Waiting response...");
string s = "";
while (string.IsNullOrEmpty(s))
{
try
{
s = ReceiveMessageFromServer();
Console.WriteLine("Response received from server.");
}
catch (Exception err)
{
Thread.Sleep(1000);
}
}
Console.WriteLine("My External Port: " + s);
//IPEndPoint ep = new IPEndPoint(IPAddress.Any, ((IPEndPoint)client.Client.LocalEndPoint).Port);
IPEndPoint ep = new IPEndPoint(IPAddress.Any, int.Parse(s));
Console.WriteLine("Start Binding on Extenal Port: " + ep.Port);
UdpClient server = new UdpClient();
server.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
server.Client.Bind(ep);
Console.WriteLine("Started. Waiting hello message...");
string c = "";
while (string.IsNullOrEmpty(c))
{
try
{
c = ReceiveMessageFromClient(server, ref ep);
Console.WriteLine("Response received from Client_A.");
Console.WriteLine("Response: " + c);
client.Connect(ep);
Console.ReadLine();
}
catch (Exception err)
{
}
}
Console.WriteLine("Sending message to Client_A...");
SendMessageToClient();
Console.WriteLine("Sended.");
Console.ReadLine();
var myRule = FirewallManager.Instance.Rules.SingleOrDefault(r => r.Name == "TEST_RULE");
FirewallManager.Instance.Rules.Remove(myRule);
}
static void SendMessageToServer()
{
byte[] data = Encoding.GetEncoding(28591).GetBytes("FROM CLIENT TO SERVER");
client.Send(data, data.Length);
}
static void SendMessageToClient()
{
byte[] data = Encoding.GetEncoding(28591).GetBytes("FROM CLIENT_B TO CLIENT_A");
client.Send(data, data.Length);
}
static string ReceiveMessageFromServer()
{
IPEndPoint serverIpEp = new IPEndPoint(IPAddress.Parse(serverIp), serverPort);
byte[] data = client.Receive(ref serverIpEp);
string receivedString = Encoding.GetEncoding(28591).GetString(data);
return receivedString;
}
static string ReceiveMessageFromClient(UdpClient server, ref IPEndPoint ep)
{
byte[] data = server.Receive(ref ep);
string receivedString = Encoding.GetEncoding(28591).GetString(data);
return receivedString;
}
我不知道哪里出了问题,也不知道如何让它发挥作用,我做了很多研究,还没有找到解决办法
对不起,英语不好