Good day all. I am more on the experienced side of Python and have written some successful file transfer applications (in python). However, I am struggling to find sufficient information or examples on how to do the same in nim. I have taken my code that I had done in Python and have attempted to translate it into nim. But not as easy as I hoped it would be. And when looking for online information on how to do, very little is found to assist with this. Please help me with this. Need to understand better on how to implement this.
Here is my translated python to nim code. Both client and server.
Server -
import net, os, strutils
const
BUFFER_SIZE = 4096
let server: Socket = newSocket()
server.bind(Port(5555))
server.listen(1)
stdout.writeLine("Server: waiting for client connection")
while true:
let (client_socket, _) = server.accept()
stdout.writeLine("Server: client connected")
while true:
let data = client_socket.recv(BUFFER_SIZE)
let filename = data.split("\r\n")[0]
let filepath = data.split("\r\n")[1]
if filename == "exit":
client_socket.close()
break
if not fileExists(filepath):
let filesize_bytes = -1.int64.pack()
client_socket.send(filesize_bytes)
continue
let filesize_bytes = fileSize(filepath).int64.pack()
client_socket.send(filesize_bytes)
let file = open(filepath, fmRead)
while true:
let bytes_read = file.read(BUFFER_SIZE)
if not bytes_read:
break
client_socket.sendall(bytes_read)
file.close()
Client -
import net, os, strutils
let client: Socket = newSocket()
client.connect("127.0.0.1", Port(5555))
stdout.writeLine("Client: connected to server on address 127.0.0.1:5555")
while true:
stdout.write("> ")
let filepath: string = stdin.readLine()
if filepath == "exit":
break
let filename = filepath.split("/")[-1]
let data = filename & "\r\n" & filepath
client.send(data)
let filesize_bytes = client.recv(8)
let filesize = filesize_bytes.unpackInt64()
if filesize == -1:
stdout.writeLine("Server: file not found")
continue
let bytes_received = 0
let download_folder = "downloads"
if not existsDir(download_folder):
createDir(download_folder)
let file = open(download_folder & "/" & filename, fmReadWrite)
while bytes_received < filesize:
let bytes_read = client.recv(BUFFER_SIZE)
if not bytes_read:
break
file.write(bytes_read)
bytes_received += len(bytes_read)
file.close()
stdout.writeLine("Server: file downloaded successfully")
client.close()
Hi @Naterlarsen somehow i don't know why i am writing... In the last trheads you worked on a client server tool. And it seems to work... This code has errors in the basic handling of the sockets...
let (client_socket, _) = server.accept()
Is this even nim? You know how to do it right...
To get you going here is a code snippet which will fit into your existing programm. the filedata will get base64 encoded it's a bit of overhead... but it won't interfer with the readlines in your client...
import std/base64
...
elif input.startsWith("download"):
...
try:
var bytes = readFile(my_path)
let encoded = encode(bytes)
client.send(encoded & "\n")
except:
client.send("file not found \n")
...