Looks like it is a major bug.
I am not familiar socket programming so I did an experiment.
I write a simple udp server and run it on amazon ec2, then I connect it using a simple udp client.
Server
static void Main (string[] args) {
int port = 5100;
Socket socket
= new Socket
(AddressFamily
.InterNetwork, SocketType
.Dgram, ProtocolType
.Udp); socket
.Bind(new IPEndPoint
(IPAddress
.Any, port
));
EndPoint bufferEndPoint
= new IPEndPoint
(IPAddress
.Any,
0);
byte[] receiveBuffer
= new byte[1024]; socket.BeginReceiveFrom(receiveBuffer, 0, receiveBuffer.Length, SocketFlags.None, ref bufferEndPoint, OnReceived, socket);
while (true);
}
private static void OnReceived (IAsyncResult ar) {
int bytesReceived;
EndPoint remoteEndPoint
= new IPEndPoint
(IPAddress
.Any,
0);
Socket socket = ar.AsyncState as Socket;
bytesReceived = socket.EndReceiveFrom(ar, ref remoteEndPoint);
Console.WriteLine(remoteEndPoint + ":" + bytesReceived);
socket
.SendTo(new byte[] { 1,
2,
3,
4,
5,
6,
7 }, remoteEndPoint
);}
Client
void Start () {
Socket socket
= new Socket
(AddressFamily
.InterNetwork, SocketType
.Dgram, ProtocolType
.Udp); socket
.Bind(new IPEndPoint
(IPAddress
.Any,
0));
socket
.Connect(new IPEndPoint
(IPAddress
.Parse("52.78.177.7"),
5100)); EndPoint bufferEndPoint
= new IPEndPoint
(IPAddress
.Any,
0);
byte[] receiveBuffer
= new byte[1024]; socket.BeginReceiveFrom(receiveBuffer, 0, receiveBuffer.Length, SocketFlags.None, ref bufferEndPoint, OnReceived, socket);
socket
.Send(new byte[] {1,
2,
3,
4 });}
private static void OnReceived (IAsyncResult ar) {
int bytesReceived;
EndPoint remoteEndPoint
= new IPEndPoint
(IPAddress
.Any,
0); Socket socket = ar.AsyncState as Socket;
bytesReceived = socket.EndReceiveFrom(ar, ref remoteEndPoint);
Debug.Log(bytesReceived);
}
And it works. The server and client can both receive udp message from each other.
Finally, I figured out why tnet udp protocol not works for at least me.
tnet's code
case Packet.RequestSetUDP: {
int port = reader.ReadUInt16();
if (port != 0 && mUdp.isActive && player.tcpEndPoint != null) {
IPAddress ip
= new IPAddress
(player
.tcpEndPoint.Address.GetAddressBytes()); SetPlayerUdpEndPoint
(player,
new IPEndPoint
(ip, port
)); } else
SetPlayerUdpEndPoint(player, null);
// Let the player know if we are hosting an active UDP connection
ushort udp = mUdp.isActive ? (ushort)mUdp.listeningPort : (ushort)0;
player.BeginSend(Packet.ResponseSetUDP).Write(udp);
player.EndSend();
// Send an empty packet to the target player to open up UDP for communication
if (player.udpEndPoint != null) {
mUdp.SendEmptyPacket(player.udpEndPoint);
}
break;
}
I used the remote client's IPEndPoint created internally when the udp message is received, and tnet create the IPEndPoint using IPAddress and port sent via tcp.
I roughly modified tnet's code and send RequestSetUDP packet via udp and it seems to work without using upnp.OpenUDP(udpPort).
Please confirm it and make a official fix if it is correct