Title: access class by ip
Tags: c++;sockets;ip
Question: 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 st75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0map<unsigned short, Connection*&gt; PortMap;
typedef st75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0map<unsigned int, PortMap&gt; 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)
AddressMap75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0iterator ipIt;
PortMap75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0iterator 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?
Comment: Thank you, it's actually as fast as Olympian's solution.

Comment: How about `pair` for map key?

Comment: consider that your average home dsl/cable link has a latency of ~40-50ms for local-ish connections. you did 64 connections in 400ms. that's pretty good.

Here is the accepted answer: 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.
Comment for this answer: But then I have to store the index as an 64 bit integer since else the value will wrap-around, right?
Comment for this answer: Wow, I'm lawsonbrittany@example.net using an unsigned long long as the key :D
Thanks both of you.
Comment for this answer: Yes, you'll need 64 bit keys.. It'll take extra memory, but provide high speed.
Comment for this answer: you could do that, or you could write your own compare operator

Here is another answer: 64 accesses into a map taking 400ms sounds horrifically slow... check your measurements.  Your map should probably be based on a combination of IP and port (not separate), since a NAT can combine clients under a specific IP.
Comment for this answer: Wow, I mean 0.4 ms! Also it's 64*64 access+ getting the pointer to the client using the address and setting some garbage data to the client(which is supposed to be the packet)
Comment for this answer: That's why I'm asking you for another solution. How would you combine them?
Comment for this answer: Yes, sorry for the typos. Your "fix" decreased the time to 0.2ms instead of 0.4ms, thanks! Do you think this is pretty much the fastest way of doing it?
Comment for this answer: even still... if that doesn't account for network traffic, 4K accesses shouldn't take long...
Comment for this answer: I see you've edited the question now and added `GetClient(Address address)`... what you have doesn't look bad and will handle NAT fine.  You might access the iterators directly though so you don't inadvertently run multiple searches (depends on compiler optimizations)... i.e. instead of `clientAddresses[ip].find(port)` you could do `portIt = ipIt->second.find(port)` and `return portIt->second;`.  It looks like you've edited the question from 0.4s to 0.4ms... that sounds much better...
Comment for this answer: What you have is good.  A combined IP/Port map might be a hair faster, but it would depend on client distribution, and it's a more complex.  You could also consider a hash function, but again, would depend on client distribution.  I'd leave it with what you have.

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 2, 'CommentCount': 3, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2012:00:11/14/12', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<c++><sockets><ip>', 'Title': 'access class by ip', 'ViewCount': 211, 'id': 13382043, 'user_AboutMe': None, 'user_AccountId': 1063601.0, 'user_DisplayName': 'grimgrom', 'user_Reputation': 680.0, 'user_Views': 57.0, 'user_id': 1824143.0}}