I’m currently working on a UDP server.
I want to redirect all incoming packets to the connected clients by using the ip address and port.
My current way of doing it looks like this:
class Connection;
typedef std::map<unsigned short, Connection*> PortMap;
typedef std::map<unsigned int, PortMap> AddressMap;
So I’m basically using two maps. The second one contains a map of all the ports using an ipv4 address(unsigned int) as a key. The PortMap uses the port as the key and it contains a pointer to the Connection class(the clients).
I speed tested it by accessing 64 clients using randomly generated ips and ports and it took ~ (EDIT : 0.4 milliseconds) to access 64 different clients 64 times.
I don’t know really if it’s slow or not. Of course it depends on the system I’m running the test on.
Here’s how I’m accessing the client using the address:
Client * GetClient(Address address)
{
AddressMap::iterator ipIt;
PortMap::iterator portIt;
unsigned int ip = address.GetAddress();
unsigned short port = address.GetPort();
/// Does the ip exist?
if((ipIt = clientAddresses.find(ip)) == clientAddresses.end())
{
return NULL;
}
/// Does the port exist?
if(clientAddresses[ip].find(port) == clientAddresses[ip].end())
{
return NULL;
}
return clientAddresses[ip][port];
}
Does anyone know another faster way of doing it?
Maybe it’ll be better to combine IP and Port..
Port < 65535. You can get key: IP * 65535 + Port, it’ll be unique for all ports and IPs.
About speed: for example we have N Ip’s, each IP has M ports.
Searching into map has efficient N log(N), so your search take N*M*log(N)*log(M).
If you combine IP and port into one key, efficient will be N*M*log(N*M).
log(N*M) = log(N)+log(M) < log(N)*log(M), for big N, M..
So, I think it’ll be better.