To link up without prior knowledge of their IP addresses, Distributed Hash Tables (DHT) are a decentralized method for peer discovery that can enable clients to find and connect with one another.
Creating a fault-tolerant infrastructure, DHT is a decentralized system that enables nodes to store and fetch data in a distributed manner. Peer-to-peer networks often implement DHT which makes it scalable. Nodes within this network hold a small fraction of the hash table, utilizing it to map values to their relevant keys.
To connect to the system, a client will reach out to a bootstrap node, an established member within the network. By doing so, they will receive a rundown of nodes or linkages to others in the DHT network from the bootstrap. After the initial step, the client can then interact with these nodes and swap important data. A specific identifier or key is created, tied to either the individual or information they aim to distribute, and the client hashes this key to complete a DHT lookup.
sample code in python
import socket
import threading
import random
# DHT to store peer information
peer_dht = {}
# Function to handle incoming connections from other peers
def handle_connection(client_socket):
while True:
data = client_socket.recv(1024) # Receive data from the peer
if not data:
break
print(f"Received data: {data.decode()}")
client_socket.close()
# Function to connect to a random peer in the DHT and send data
def connect_to_peer():
if not peer_dht:
print("No peers available.")
return
peer_ip, peer_port = random.choice(list(peer_dht.items()))
peer_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
peer_socket.connect((peer_ip, peer_port)) # Connect to the peer
while True:
message = input("Enter a message to send: ")
if message.lower() == "exit":
break
peer_socket.sendall(message.encode()) # Send data to the peer
except ConnectionRefusedError:
print("Connection refused.")
finally:
peer_socket.close()
# Main function to start the program
def main():
# Get the local IP address
local_ip = socket.gethostbyname(socket.gethostname())
# Start a listening socket to accept incoming connections
listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listen_socket.bind((local_ip, 8000)) # Use a specific port number
listen_socket.listen(1)
print(f"Listening for incoming connections on {local_ip}:8000")
while True:
client_socket, client_address = listen_socket.accept()
print(f"Connected to peer at {client_address[0]}:{client_address[1]}")
# Add the peer to the DHT
peer_dht[client_address[0]] = client_address[1]
# Start a new thread to handle the connection
threading.Thread(target=handle_connection, args=(client_socket,)).start()
listen_socket.close()
# Entry point of the program
if __name__ == '__main__':
main()