Try to set connection between server and user client

I'm writing an server that .read() and .write() the u8 string. Server also stores a variable - A=1.
server get a value of variable B, and than
do this : A = A * B. (Server must save new value!)
and than server sholud to reply to client in u8 string form, should return a new value of A.

When I connect the client to server, it writes:

New connection: 127.0.0.1:1639

On the client terminal I can also see:

Please, write the value of B:

And than, when I write number/numbers, server writes me the error:

thread '' panicked at 'called Result::unwrap() on an Err value: ParseIntError { kind: InvalidDigit }', main.rs:14:41

So, what should I do to fix it?

My server:

fn handle_client(mut stream: TcpStream) {

   let mut data = [0 as u8; 30]; // using 30 byte buffer

   let mut a: i32 = 1;

   while match stream.read(&mut data) {

       Ok(size) => {

           // конвертируем полученную строку из u8  в String

          let temp = str::from_utf8(&data).unwrap();     

          // конвертируем String в i32     

          let temp: i32 = temp.parse().unwrap();

           // изменяем значение а

           a = a * temp;

           // теперь i32 конвертируем в String            

           let st = a.to_string();

           // String в u8

           let data = st.as_bytes();

           // и отдаём эту инфу клиенту

           stream.write(&data[0..size]).unwrap();

           true

       },

       Err(_) => {

           println!("An error occurred, terminating connection with {}", stream.peer_addr().unwrap());

           stream.shutdown(Shutdown::Both).unwrap();

           false

       }

   } {}

}

fn main() {

   let listener = TcpListener::bind("0.0.0.0:3333").unwrap();

   // accept connections and process them, spawning a new thread for each one

   println!("Server listening on port 3333");

   println!("A = 1");

   for stream in listener.incoming() {

       match stream {

           Ok(stream) => {

               println!("New connection: {}", stream.peer_addr().unwrap());

               thread::spawn(move|| {

                   // connection succeeded

                   handle_client(stream)

               });

           }

           Err(e) => {

               println!("Error: {}", e);

               /* connection failed */

           }

       }

   }

   // close the socket server

   drop(listener);

}

You can't use stream.read like that. Consider the following scenario:

I perform two writes:

  1. [1, 2, 3, 4]
  2. [5, 6, 7, 8, 9]

It is now possible for the calls to stream.read to return the following values:

  1. size = 3, data = [1, 2, 3, 0, 0]
  2. size = 2, data = [4, 5, 3, 0, 0]
  3. size = 4, data = [6, 7, 8, 9, 0]

Note that data was [0, 0, 0, 0, 0] before we started above.

Anyway, this explains why the integer is not valid. Your &data will be longer than the number of bytes that you received, so it includes a bunch of extra characters. Additionally you don't handle e.g. if the written number is cut in half into two reads.

The TCP protocol does not include any sort of boundary, so you must include such boundaries as part of the message you write, e.g. you could first write the number of bytes sent so the receiver knows when it got all of them.

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.