I'm trying to implement mainline dht. While implementing I found it easier to use multithreading to handle requests and send requests at the same time. But it's impossible for a singular port to both send and receive at the same time. There's two solutions I thought of, one of those would be using different ports for receiving and sending, however in mainline dht it seems like whenever you send a request, nodes will remember you based on the port you send the request on. Is it possible to still implement a different port for receiving and sending?
Asked
Active
Viewed 43 times
1
-
It is not impossible for a singular port to receive and send at the same time. – user253751 Feb 17 '23 at 20:31
-
Yes I'm aware I mentioned it in my post. This question is about sending from one port and receiving from another – raz Feb 17 '23 at 20:35
-
Use the same port. – user253751 Feb 17 '23 at 20:37
-
But that wasn't my question and doesn't solve anything. I'm trying to figure out if this is a possible solution for the protocol – raz Feb 17 '23 at 20:40
-
I don't see why they would have made that possible. Just use the same port. – user253751 Feb 17 '23 at 20:48
1 Answers
1
The DHT requires that the same port is used for sending and receiving.
But it's impossible for a singular port to both send and receive at the same time.
Sockets are thread-safe, you can issue send and receive syscalls to the same socket at the same time.
If you want to load-balance reading across multiple threads you can open multiple sockets bound to the same port via SO_REUSEPORT
but that shouldn't be necessary because any regular DHT implementation will only see a dozen packets per second, perhaps with short burts into the thousands, something that a single core can comfortably handle.

the8472
- 40,999
- 5
- 70
- 122
-
Well the class I'm using for sockets doesn't really support multithreading but I can worst case scenario use dlls. I guess you don't need multiple threads but I feel like implementation would be easier with that (for example executing get_peers while also receiving requests) – raz Feb 19 '23 at 11:29
-
1A DHT can be easily implemented on a single thread by using non-blocking IO, an epoll()/select() loop to check read/write readiness and if there's something that needs a timeout (e.g. when waiting for responses) then polling with a timeout can provide ticks. I'm doing something like that [in my Rust DHT impl](https://github.com/the8472/bt-dht-rs/blob/cfd58cad97306449120f1aa693b9c3547dda1fe0/src/main.rs#L80-L101). Using threads is possible, but generally overkill. Actually, even a blocking IO API should be fine as long as you can set a read timeout. – the8472 Feb 19 '23 at 14:34
-
-
1Not a C# expert, but the Socket class has `Blocking` and `Poll` properties, so I guess that's supported. – the8472 Feb 19 '23 at 16:36
-
Actually I still have one question left, how would you handle ping requests in just one thread and loop? Do you save the node and bucket every time you need to ping? – raz Feb 20 '23 at 04:28
-
-
in my implementation I keep track of outgoing requests, including pings, because I associate some state with them. The bucket can be found by the node ID of the responding node. that has nothing to do with threads or not, just with overall state associated with the dht. – the8472 Feb 20 '23 at 13:04
-
I'm dumb this makes a lot of sense you can just go to the appropriate bucket in the routing table based on the id – raz Feb 20 '23 at 13:35