I need help fixing an issue

Hello everyone, i am relatively new in using rust, just getting started as a rust developer. I have fallen into a bug that is proving a bit challenging to fix, i'm requesting for help.
In this project, a server and client are supposed to transfer with each other. In my client-side code, I send the data like this


    // Connecting to the server
    match TcpStream::connect(server_address)  {
        Ok(mut stream) => {
            println!("Connected to Server");

            // Send branch code back to the server
            let branch_code = format!("bcode~{}", branch_code);
            if let Err(e) = stream.write_all(branch_code.as_bytes()){
                error!("Error writing branch message: {:?}", e);
                // return;
            }else {
                println!("Branch code sent successfully")
            };
            println!("Branch code: {}", branch_code);
    
            // Receive an acknowldgement from the server
            let mut response = String::new();
            if let Err(e) = stream.read_to_string(&mut response){
                error!("Error reading response: {:?} ", e)
            };
            println!("1st response: {}", response);
            
            if response.trim() == "OK" {
                // Send base64 content to the server
                let file_message = format!("~{}~", base64_content);
                if let Err(e) = stream.write(file_message.as_bytes()){
                    error!("Error writing file message to stream: {:?}", e);
                    // return;
                };
    
                // Receive an acknowledgement from the server
                let mut response = String::new();
                if let Err(e) = stream.read_to_string(&mut response){
                    error!("Error reading response from stream: {:?}", e)
                };
    
                if response.trim() == "OK"{
                    println!("Sales report transferred successfully")
                } else {
                    error!("Error in sales transfer")
                }
            } else {
                error!("Error in branch code acknowledgement")
            }

This how i expect to read the sent data from the server-side.

fn handle_client(mut stream : TcpStream){
    println!("Starting to handle the client");
    let mut buffer = Vec::new();
    if let Err(e) = stream.read_to_end(&mut buffer) {
        eprintln!("Error reading branch code: {:?}", e);
        return;
    }

    // Process the branch code
    let branch_code = String::from_utf8_lossy(&buffer);
    println!("Received branch code: {}", branch_code);
}

I am trying to read the data sent by the server, but nothing happens. The server just stalls, after the first println! "Handling client".

I would be happy to be helped. Cheers

The call to read_to_end will only return if the stream has been closed in the read direction. However, your client does not close its write direction before calling read_to_string.

To fix this, add a call to shutdown after writing in the client.

Hm, I see you need to write again later. You can't do that after calling shutdown.

You will need some other mechanism to tell the reader when to stop reading. For example, you could send a newline and have the server read until a newline. Or you could send the length first, so that the server knows can use read_exact to read the correct number of bytes.

2 Likes

Thanks for replying let me try that.

I am happy to inform you that that worked. I sent the length and used read_exact.

After the reading action has been done, the server needs to send an "OK", to the client, which in turn sends some data encoded using base64. Here is the how i intend the client-side to operate.

match TcpStream::connect(server_address)  {
        Ok(mut stream) => {
            println!("Connected to Server");

            // Send branch code back to the server
            let branch_code = format!("bcode~{}", branch_code);
            let branch_length = branch_code.len();
            if let Err(e) = stream.write_all(&(branch_length as u32).to_be_bytes()) {
                error!("Error writing the length: {:?}", e)
            }
            if let Err(e) = stream.write_all(branch_code.as_bytes()){
                error!("Error writing branch message: {:?}", e);
                // return;
            }else {
                println!("Branch code sent successfully")
            };
            println!("Branch code: {}", branch_code);
    
            // Receive an acknowldgement from the server
            // Reading the "OK" lenght
            let mut resp_length_buff = [0; 4];
            if let Err(e) = stream.read_exact(&mut resp_length_buff){
                error!("Error reading response: {:?} ", e)
            };
            let length = u32::from_be_bytes(resp_length_buff);
            
            // Reading the "Ok" response
            let mut response_buff = vec![0; length as usize];
            stream.read_exact(&mut response_buff).expect("Failed to read response");
            let response = String::from_utf8_lossy(&response_buff);
            println!("1st response: {}", response);
            
            if response.trim() == "OK" {
                // Send base64 content to the server
                let file_message = format!("~{}~", base64_content);
                if let Err(e) = stream.write(file_message.as_bytes()){
                    error!("Error writing file message to stream: {:?}", e);
                    // return;
                };
    
                // Receive an acknowledgement from the server
                let mut response = String::new();
                if let Err(e) = stream.read_to_string(&mut response){
                    error!("Error reading response from stream: {:?}", e)
                };
    
                if response.trim() == "OK"{
                    println!("Sales report transferred successfully")
                } else {
                    error!("Error in sales transfer")
                }
            } else {
                error!("Error in branch code acknowledgement")
            }

            if stream.shutdown(Shutdown::Both).is_err(){
                error!("Failed to close the connection")
            }
        }
        Err(err) => {
            error!("Failed to connect to server: {:?}", err);
            // return;
        }
    } 

The server should to send the OK message, after reading the branch_code, and afterwards read data the sent by the client-side.

//server-side/src/main.rs

//previous code of getting the branch_code

    // Send acknowledgment to the client
    if let Err(e) = stream.write_all(b"OK") {
        error!("Error writing acknowledgment to stream: {:?}", e);
        return;
    };

    // Receive Base64 content from client
    let mut base64_content = String::new();
    if let Err(e) = stream.read_to_string(&mut base64_content) {
        error!("Error reading Base64 content: {:?}", e);
        return;
    };
    println!("Received Base64 content: {}", base64_content);

What can i do to ensure that all these actions take place. ie, after the code was read, the terminal just stopped, the client didn't read the OK message and thus no content was sent to the server.

How can I imporve my scripts? :smiling_face_with_tear:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.