I'm trying to send UDP packets from one client to another. Let C1 be the client I'm using to receive data and C2 the client who will send the data. What I'm doing:
Ask a STUN server for the public IP addresses and ports of both clients.
I inform each client of the others IP address and public port.
C1 sends a packet to C2 on it's public address and port and starts listening for packets. At the same time C2 starts sending packets with the data I want to be transmited.
C1 just hangs on receiving a packet that never arrives. am I doing the UDP hole puching wrong?
I am testing this with both clients on the same computer on the same network but the server is on a server on another network with a public IP. What I'm trying to say is that the public address for both clients is the same while I'm testing, is this a problem?
UPDATE:
I know now that my router allows for hairpinning. I fowarded the UDP ports on my router and using the public IP address I can send packets from one client to the other.
This is the code I'm using to test if I can do hole punching in C#:
static UdpClient udpClient = new UdpClient(30001);
static IPAddress remoteIp;
static int remotePort;
static void Main(string[] args)
{
// Send packet to server so it can find the client's public address and port
byte[] queryServer = Encoding.UTF8.GetBytes("something");
udpClient.Send(testMsg, testMsg.Length, new IPEndPoint(IPAddress.Parse("199.254.173.154"), 30000));
// Wait for a response from the server with the other client's public address and port
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
byte[] dataJsonBytes = udpClient.Receive(ref sender);
JObject json = JObject.Parse(Encoding.UTF8.GetString(dataJsonBytes));
remoteIp = IPAddress.Parse(json["IP"].ToString());
remotePort = Int32.Parse(json["port"].ToString());
// Start spamming the other client with packets and waiting for response
Thread sendingThread = new Thread(sendPacket);
Thread receivingThread = new Thread(receivePacket);
sendingThread.Start();
receivingThread.Start();
Console.ReadLine();
}
private static void sendPacket()
{
byte[] udpMessage = Encoding.UTF8.GetBytes("Forcing udp hole punching!!\n");
while (true)
{
udpClient.Send(udpMessage, udpMessage.Length, new IPEndPoint(remoteIp, remotePort));
Thread.Sleep(100);
}
}
private static void receivePacket()
{
IPEndPoint senderEp = new IPEndPoint(IPAddress.Any, 0);
udpClient.Client.ReceiveTimeout = 500;
while (true)
{
try
{
byte[] receivedData = udpClient.Receive(ref senderEp);
Console.Write(Encoding.UTF8.GetString(receivedData));
}
catch (Exception)
{
Console.Write("Timeout!!\n");
}
}
}
UPDATE 2:
With the help of @Tahlil I was able to figure out that the algorithm I used to check the NAT type was flawed and I was trying to do hole punching behind a symmetric NAT. So the problem was not noticing a mistake on my code... I recommend asserting the NAT type with certainty to all that face the same problem.
Thank you all for your help.