How can i send a confirmation message after i receive a file from another socket

47 views Asked by At

Here is my server.py this one waits until a client connects and receive a file name and gives back the file (an audio file)

"""
Server receiver of the file
"""
from pyngrok import ngrok, conf
import socket
import tqdm
import os

# device's IP address
SERVER_HOST = "0.0.0.0"
SERVER_PORT = 5001
# receive 4096 bytes each time
BUFFER_SIZE = 4096
SEPARATOR = "<SEPARATOR>"

# file with the public url provided by ngrok
FILE = "public_url.txt"

# create the server socket
# TCP socket
s = socket.socket()
# bind the socket to our local address
s.bind((SERVER_HOST, SERVER_PORT))
# enabling our server to accept connections
# 5 here is the number of unaccepted connections that
# the system will allow before refusing new connections
s.listen(5)
#print(f"[*] Listening as {SERVER_HOST}:{SERVER_PORT}")
# accept connection if there is any

# ngrok connection 


if os.path.exists(FILE):
    os.remove(FILE)

conf.get_default().config_path = "ngrok.yml"

tcp_tunnel = ngrok.connect(SERVER_PORT,"tcp")

with open("public_url.txt","w") as file:
    file.write(tcp_tunnel.public_url)

print(f"[*] Listening as {tcp_tunnel.public_url}")

file_sent = False

while not file_sent:

    
    client_socket, address = s.accept() 
    # if below code is executed, that means the sender is connected
    print(f"[+] {address} is connected.")

    # receive the file infos
    # receive using client socket, not server socket
    filename = client_socket.recv(BUFFER_SIZE).decode("utf-8")
    

    if os.path.exists(filename):

        filesize = os.path.getsize(filename)
        filesize_str = str(filesize)
        client_socket.send(filesize_str.encode())

        # remove absolute path if there is
        filename = os.path.basename(filename)
        # convert to integer
        
        client_socket.recv(BUFFER_SIZE).decode("utf-8")

        # start receiving the file from the socket
        # and writing to the file stream
        progress = tqdm.tqdm(range(filesize), f"Sending {filename}", unit="B", unit_scale=True, unit_divisor=1024)
        
        

        with open(filename, "rb") as f:
            while True:
                # read the bytes from the file
                bytes_read = f.read(BUFFER_SIZE)
                if not bytes_read:
                    # file transmitting is done
                    
                    break
                # we use sendall to assure transimission in 
                # busy networks
                client_socket.sendall(bytes_read)
                # update the progress bar
                progress.update(len(bytes_read))

        progress.close()

        print("sali")

        #s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
        ack = client_socket.recv(BUFFER_SIZE).decode()
        print (ack)
        
        
    else:
        client_socket.send("[*] The file does not exist".encode())
        print(f"[*] The file {filename} does not exist")
        break
        
    # close the client socket
    client_socket.close()
    print()
    
# close the server socket
s.close()


Server.py:

Client.py: 
"""
Client that sends the file (uploads)
"""
import socket
import tqdm
import os
import argparse

SEPARATOR = "<SEPARATOR>"
BUFFER_SIZE = 1024 * 4 #4KB

def get_file(filename, host, port):
    # get the file size
    
    # create the client socket
    s = socket.socket()
    print(f"[+] Connecting to {host}:{port}")
    s.connect((host, port))
    print("[+] Connected.")

    # send the filename and filesize
    s.send(f"{filename}".encode())

    msg = s.recv(BUFFER_SIZE).decode()
    
    if msg == "[*] The file does not exist":
        print(f"[*] The file {filename} does not exist")
        return

    filesize = int(msg)

    s.send(f"{filename}".encode())

    # start sending the file
    progress = tqdm.tqdm(range(filesize), f"Receiving {filename}", unit="B", unit_scale=True, unit_divisor=1024)
    with open("./audios/"+filename, "wb") as f:
        while True:
            # read 1024 bytes from the socket (receive)
            bytes_read = s.recv(BUFFER_SIZE)
            if not bytes_read:    
                # nothing is received
                # file transmitting is done
                s.shutdown(socket.SHUT_WR)
                break
            # write to the file the bytes we just received
            f.write(bytes_read)
            # update the progress bar
            progress.update(len(bytes_read))
            
            
            

    print(f"[+] {filename} was received succesfully")
    
    # Send a completion message to the server
    s.sendall("[*] File received successfully".encode())
    

    # close the socket
    s.close()


get_file("audio.mp3", "0.tcp.ngrok.io", 14755)

#get_file("10mb.ogg", "2.tcp.ngrok.io", 15255)
#get_file("5mb.ogg", "2.tcp.ngrok.io", 15255)

My issue right now is that when i both my server and client i can get the audio file but i dont know what happens that my client never gets out of loop, also when i delete the lines where i send and receive the message of confirmation my program works just fine

What can i do about it?

Note: im sorry if my code is buggy im trying to learn how to use sockets for a project of my university

0

There are 0 answers