Skip to main content

SERVER/CLIENT cannot send and recieve data on the same socket, server close server after first attempt

Hi im trying to create a backup function for my program, the idea is to copy and send all the files from one especific folder from my client to the server, the issue here is everytime i send the file name and size of every file as a list the server close the conecction after its recieve but i need the server to ask the client for the data of the files itself, the main is like follows

make a list of all files on folder -------> send the list of Files and size via sockets ------> recieve and ask back the file i want to copy one by one ----->send the data of the actual file -----> repeat until the list is over

it supose i handle the data send using the ready read signal but for some reason i cant send the actual data, the conecction is closed, this is a good way on handling the data? or its better to send all data at once? like filename + <SEP> + datafile theres any way to split the data recive without messing the data of the file???

i add my actual code, the client is in C++ and the server is in python, any help is welcome

Server.py

def servidorMk3():
    host = socket.gethostname()
    host_port = 8000
    host_ip = socket.gethostbyname(host)
    buffer = 1024
    cnt = 0
    code_end = "<END>"
    code_ok = "<OK>"
    code_fin = "<FIN>"
    code_bad = "<BAD>"
    nombre = []
    tamano = []
    
    print (f"Servidor Mk3")
    print (f"Ip del servidor: " + host_ip)
    log("Inicio del servidorMk3 " + host_ip)
    
    # while True:
    #     send_UDP_broadcast(host_ip)
    #     ip = lisent_UDP_broadcast()
    #     if ip:
    #         break
    #     else:
    #         continue
    
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as tcp_conn:
        tcp_conn.bind((host_ip, host_port))
        tcp_conn.listen(2)
        con, adrs = tcp_conn.accept()
        with con:
            cnt += 1
            print (f"Conecion Exitosa")
            log("Connecion exitosa con el server: " + adrs[0])
            if cnt > 20:
                log("Fin del ciclo")
            else:
                while True:
                    # start to recieve the list of files
                    while True:         # start to fill the socket
                        data = con.recv(buffer)
                        if not data:     # if theres no data close the loop
                            break
                        if code_end.encode("utf8") in data:  # if found <END>, ends the current element
                            break
                    data = data.decode("utf8")
                    elemt = []
                    elemt = data.split("<SEPARATOR>")
                    if code_fin in data:  # if found <FIN>, the list is over
                         break     
                    
                    ##  Erease the empty elements
                    ##  **************************************************
                    if code_end in elemt: elemt.remove(code_end)
                    #print("antes de borrar elementos")
                    #for a in range(len(elemt)):
                    #    print(elemt[a])
                    elemt = list(filter(None, elemt))
                    print ("despues de borrar")
                    for a in range(len(elemt)):
                        print(elemt[a])
                    if not elemt:
                        nombre, tamano = elemt[:2]
                    else:
                    #    print("Elemento vacio")
                        break
                    ## **************************************************
                    
                    #  now i ask what file i want to recieve
                    #request_files(nombres, adrs, host_port)
                # creates 2 independent list then iterate and asign names and size respectively
                
                for a in range (len(nombre)):
                   # here i ask the names and start asking the client for it
                    con.send(nombre[a].encode("utf8"))
                    print (nombre[a])
                    while True:    # recive the data file
                        file_data = con.recv(buffer)      
                        if not file_data:
                            break
                    #     # revisar como comparar el tamaƱo que ya tengo vs el tamaƱo que recibo
                    #     #https://stackoverflow.com/questions/449560/how-do-i-determine-the-size-of-an-object-in-python
                    #     if int(nombres[1]) == sys.getsizeof(file_data):
                    #         break
                    
                    # # Here i save the files to disk
                    directorio = crear_directorio()
                    if directorio == "<BAD>":
                        print(" no se puede crear la ubicacion")
                        print(type(directorio))  # revisar el tipo que regresa esta funcionĀ”Ā”Ā”Ā”
                        print(directorio)
                    else:
                        file_name = directorio + nombre[a]  # path to the file,   
                        file_size = int(tamano[a])   # size of file
                        file_create = open(file_name, 'wb')  # open file for writing in binary 
                        while (file_data):   # creacion y escritura del archivo
                            file_create.write(file_data)   # writes to the file
                        file_create.close()     #close the file
                        check = os.path.getsize(file_name)  # returns the size of the file
                    
                        if check == file_size:
                            #con.send(code_ok.encode())
                            log("archivo " + nombre[a] + " creado, tamaƱo: " + tamano[a])
                        else:
                            #con.sendall(code_bad.encode())
                            log("No se pudo crear el archivo: " + nombre[a])
            
            log("Respaldo de Archivos completado")
            print(f"Respaldo de archivos terminada")

client.c++

Server::Server() {    // server constructor
     Gen gen;  // Logs 

     QObject::connect(TCP_socket, &QTcpSocket::readyRead,  [&]() {  //  the idea is to handle here the data of the file
            QString dataread;
            gen.Log
            QByteArray data, block_file;
            QDataStream salida(TCP_Socket);
            QStringList File_Name;
            QDir directorio("Data/");
            bool yes;

            File_Name = directorio.entryList (QStringList() << "*.db" << "*.DB" << "*.Db" << "*.dB" , QDir::Files  );
            data = TCP_socket->readAll();
            dataread.append(data);

            foreach (QString lista, File_Name) {
                     block_file.clear();
                     if (lista == dataread) {
                         QFile Archivo("Data/" + lista);
                         Archivo.open(QIODevice::ReadOnly);
                         block_file = Archivo.readAll();
                         gen.Log(Lista);
                      }
                    if (TCP_socket->isValid() ) {
                          gen.Log("antes de escribir");
                          salida.writeRawData ( (char*)(block_file.data()), block_file.size() );                    
                          yes = TCP_socket->flush();
                          TCP_socket->waitForBytesWritten();
                          yes == true ? gen.Log("Datos Enviados: " + lista) : gen.Log("No se envio la data del archivo: " + lista);
                      }
               }
      });


void Server::TCP_Request_Send() {     // actual backup function
      Gen L; 
      QString Ip ("192.168.1.123");     // need to add a broadcast function to retrieve the ip
       qint64 filesize;
       bool yes = false;
       QByteArray block, block_file; 
      QStringList File_name;
       QDir directorio("Data/");

       File_Name = directorio.entryList (QStringList() << "*.db" << "*.DB" << "*.Db"<< "*.db", QDir::Files );
       File_Name.append ("<FIN>");
       L.Log ("..........Lista de Archivos");

       if (TCP_socket->state() == QAbstractSocket::UnconnectedState ) {
               L.Log("Before connection");
               TCP_socket->connectToHost( Ip, 8000, QIODevice::WriteOnly);
               if (TCP_socket->waitForConnected(5000) ) {
                       QDataStream salida(TCP_socket);
                       foreach ( QString files, File_Name) {
                             QFile Archivo ("Data/" + files);
                             std::string nombre = files.toStdString();
                             L.Log (QString::fromStdString(nombre) );
                             Archivo.open (QIODevice::ReadOnly);
                             block_file = Archivo.readAll();
                             filesize = Archivo.size();
                             block.clear();
                         
                             if (files == "<FIN>") {
                                    block.append ("<FIN><SEPARATOR><END>");
                             } else {
                                    block.append (QString::fromStdString(nombre) + "<SEPARATOR>"  + QString::number(filesize) + "<SEPARATOR>" + "<END>" );
                                    if (block.isEmpty() == true) {
                                             continue;    // if empty the for continues
                                        }
                             }

                           L.Log ("despues de block");
                           if (TCP_socket->isValid() ) {
                                 L.Log ("antes de escribir");
                                 salida.writeRawData ( (char*)(block.data()), block.size() );
                                 yes = TCP_socket->waitForBytesWritten();
                                L.Log (QString::fromUtf8(block.constData(), block.size()  ) );
                                yes == true ? L.Log ("nombre " + files + " enviado") : L.Log ("no se pudo enviar el nombre" + files );
                          }
               Archivo.close();
          };
       }
     }
  }

EDIT: I did follow Tims Roberts advice and get rid of the while true and also sending all the info and data from each file all at once it works, but for some reason the data is not reaching correctlly, i should recive the first elemnt but i recieve the second and the list start from there.

i should get something like this

Conecion Exitosa
despues de borrar
0 ..  Ciclo_OI.db
1 ..  25698
TamaƱo esperado: 25698 ... tamaƱo real: 25698

despues de borrar
0 .. Ciclo_OI_2020_2021.db
1 .. 32768
TamaƱo esperado: 32768 ... tamaƱo real 32768

but i get this instead, that of course is totally wrong

Conecion Exitosa
despues de borrar
0 .. <END>Ciclo_OI_2020_2021.db
1 .. 32768
TamaƱo esperado: 32768 ... tamaƱo real 324 

despues de borrar
0 .. <END>Ciclo_PV_2020_2021.db
1 .. 32768
TamaƱo esperado: 32768 ... tamaƱo real 66 

my current code is as follows

with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as tcp_conn:
    tcp_conn.bind((host_ip, host_port))
    tcp_conn.listen(1)
    con, adrs = tcp_conn.accept()
    print (f"Conecion Exitosa")
    log("Connecion exitosa con el server: " + adrs[0])
    
    while True:
        #empieza a recibir la lista de los archivos
        while True:         # recibe la info en general
            data = con.recv(buffer)
            if not data:     # si no hay informacion se cierra el ciclo
                break
            if code_end.encode("utf8") in data:  # si llega <END>, termino el elemento actual
                break
        
        if code_fin.encode("utf8") in data:  # si llega <FIN>, se acabo la lista
            break     
        elemt = []
        elemt = data.split(b'<SEP>')

        
        ##  Elimina los elementos vacios
        ##  **************************************************
        
        # for a in range(len(elemt)):
        #     if code_end.encode("utf8") in elemt[a]:
        #         elemt[a] = elemt[a].strip(b'<END>')
                # elemt[a] = elemt[a].remove(code_end.encode("utf8"))
        #print("antes de borrar elementos")
        #elemt = list(filter(None, elemt))   # erase empty spaces
        if len(elemt) < 3:
            nombre = elemt[0].decode("utf8")
            print(nombre)
            size = elemt[1].decode("utf8")
            dataFile =  elemt[2]
            print (f" menor a {len(elemt)}")
        if len(elemt) > 3:
            nombre = elemt[1].decode("utf8")
            size = elemt[2].decode("utf8")
            dataFile =  elemt[3]
            print (f" mayor a {len(elemt)}")
        #for a in range(len(elemt)):  # remove <END>
        #    if code_end.encode("utf8") in elemt[a]:
        nombre.replace("<END>","")     # get rid of end
        nombre = nombre.strip()   # erase empty spaces
        size = size.strip()
        #size = list(filter(None, size))
        
        # there should be 3 elemnts now name, size, datafile
        print ("despues de borrar")
        #for a in range(len(elemt)):
        #    print(elemt[a].decode("utf8"))
        # if not elemt:
        #     nombre, tamano = elemt[:2]
        # else:
        # #    print("Elemento vacio")
        #     break
        ## **************************************************
        
        #  ahora ahy que pedir cual archivo nos mande
        #request_files(nombres, adrs, host_port)
    
    # crear 2 listas independientes y luego iterarlas, asignarles los nombres y tamanos respectivamente
    # for a in range (len(nombre)):
    #     #  aqui tomar los nombres y pedirlos    
    #     #con.send(nombre[a].encode("utf8"))
    #     print (nombre[a])
    #     while True:    # recibe la data del archivo
    #         file_data = con.recv(buffer)      
    #         if not file_data:
    #             break
        #     # revisar como comparar el tamaƱo que ya tengo vs el tamaƱo que recibo
        #     #https://stackoverflow.com/questions/449560/how-do-i-determine-the-size-of-an-object-in-python
        #     if int(nombres[1]) == sys.getsizeof(file_data):
        #         break
        
        # # Aqui guardo los archivos a disco revisar la funcion mk2
        directorio = crear_directorio()
        if directorio == "<BAD>":
            print(" no se puede crear la ubicacion")
            print(type(directorio))  # revisar el tipo que regresa esta funcionĀ”Ā”Ā”Ā”
            print(directorio)
        else:
            print(f"0 .. {nombre}")
            print(f"1 .. {size}")
            #print (dataFile)
            file_name = directorio + nombre  # path to the file,   
            file_size = int(size)   # size of file
            
                   # actual data of the file
            file_create = open(file_name, 'wb')  # open file for writing in binary 
            #while (dataFile):   # creacion y escritura del archivo
            file_create.write(dataFile)   # writes to the file
            file_create.close()     #close the file
            check = os.path.getsize(file_name)  # returns the size of the file
            print (f"TamaƱo esperado: {file_size} ... tamaƱo real {check} ")
            
            if check == file_size:
                #con.send(code_ok.encode())
                log("archivo " + file_name + " creado, tamaƱo: " + file_size)
            else:
                #con.sendall(code_bad.encode())
                log("No se pudo crear el archivo: " + file_name)
    
    log("Respaldo de Archivos completado")
    print(f"Respaldo de archivos terminada")


source https://stackoverflow.com/questions/71945497/server-client-cannot-send-and-recieve-data-on-the-same-socket-server-close-serv

Comments

Popular posts from this blog

ValueError: X has 10 features, but LinearRegression is expecting 1 features as input

So, I am trying to predict the model but its throwing error like it has 10 features but it expacts only 1. So I am confused can anyone help me with it? more importantly its not working for me when my friend runs it. It works perfectly fine dose anyone know the reason about it? cv = KFold(n_splits = 10) all_loss = [] for i in range(9): # 1st for loop over polynomial orders poly_order = i X_train = make_polynomial(x, poly_order) loss_at_order = [] # initiate a set to collect loss for CV for train_index, test_index in cv.split(X_train): print('TRAIN:', train_index, 'TEST:', test_index) X_train_cv, X_test_cv = X_train[train_index], X_test[test_index] t_train_cv, t_test_cv = t[train_index], t[test_index] reg.fit(X_train_cv, t_train_cv) loss_at_order.append(np.mean((t_test_cv - reg.predict(X_test_cv))**2)) # collect loss at fold all_loss.append(np.mean(loss_at_order)) # collect loss at order plt.plot(np.log(al...

Sorting large arrays of big numeric stings

I was solving bigSorting() problem from hackerrank: Consider an array of numeric strings where each string is a positive number with anywhere from to digits. Sort the array's elements in non-decreasing, or ascending order of their integer values and return the sorted array. I know it works as follows: def bigSorting(unsorted): return sorted(unsorted, key=int) But I didnt guess this approach earlier. Initially I tried below: def bigSorting(unsorted): int_unsorted = [int(i) for i in unsorted] int_sorted = sorted(int_unsorted) return [str(i) for i in int_sorted] However, for some of the test cases, it was showing time limit exceeded. Why is it so? PS: I dont know exactly what those test cases were as hacker rank does not reveal all test cases. source https://stackoverflow.com/questions/73007397/sorting-large-arrays-of-big-numeric-stings

How to load Javascript with imported modules?

I am trying to import modules from tensorflowjs, and below is my code. test.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title </head> <body> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@2.0.0/dist/tf.min.js"></script> <script type="module" src="./test.js"></script> </body> </html> test.js import * as tf from "./node_modules/@tensorflow/tfjs"; import {loadGraphModel} from "./node_modules/@tensorflow/tfjs-converter"; const MODEL_URL = './model.json'; const model = await loadGraphModel(MODEL_URL); const cat = document.getElementById('cat'); model.execute(tf.browser.fromPixels(cat)); Besides, I run the server using python -m http.server in my command prompt(Windows 10), and this is the error prompt in the console log of my browser: Failed to loa...