Reputation: 73
I wrote a basic file sharing app in Python, but it seems to cut out much of the end of a file, which could be problematic to say the least. It uses the "kademlia" library, and it stores the data directly on the DHT. It's about ~4000 characters left out. Am I doing something wrong or is this a bug with the library?
import asyncio, io, hashlib, json, os
from kademlia.network import Server
CHUNKSIZE = 6000
BOOTSTRAP = False
PORT = 8103
nodes = [("127.0.0.1", 8103)]
def hash_(file: io.BytesIO):
hash = hashlib.sha256()
while True:
val = file.read(1024*16)
if not val:
break
hash.update(val)
file.seek(0)
return hash.hexdigest()
def size(file: io.BytesIO) -> int:
file.seek(0, io.SEEK_END)
val = file.tell()
file.seek(0)
return val
async def host(node: Server, file: io.BytesIO):
size_ = size(file)
chunks = size_ // CHUNKSIZE
fhash = hash_(file)
await node.set(fhash, json.dumps(
{'chunks': chunks, 'size': size_, 'name': os.path.basename(file.name)}
))
for i in range(0,chunks):
await node.set(f"{fhash}/{i}", file.read(CHUNKSIZE))
return fhash
async def download(node: Server, file: io.BytesIO, hash: str):
meta = await node.get(hash)
assert meta
meta = json.loads(meta)
for i in range(0,meta['chunks']):
file.write(await node.get(f"{hash}/{i}"))
file.flush()
async def run():
# Create a node and start listening on port provided.
node = Server()
await node.listen(PORT)
if BOOTSTRAP: await node.bootstrap(nodes)
while True:
inp = (await asyncio.to_thread(input, ">")).split(' ')
if inp[0] == 'host':
with open(inp[1], 'rb') as f:
print(await host(node, f))
if inp[0] == 'download':
with open('downloaded', 'wb') as f:
await download(node, f, inp[1])
if inp[0] == 'exit':
exit()
if __name__ == '__main__':
asyncio.run(run())
What I got (in git diff format)
Upvotes: 0
Views: 20