Xin
Xin

Reputation: 123

Rust TcpStream write/write_all confusing behavior

Purpose

Testing a webserver implementation on The Rust Programming Language

Problem encountered:

TcpStream.write_all(some_large_file) wouldn't work, details below:

let contents = &fs::read(filename).unwrap()[..];
let response_headers = format!(
    "{}\r\nContent-Length: {}\r\n{}\r\n\r\n",
    status_line,
    contents.len(),
    content_type(filename)
);

stream.write_all(response_headers.as_bytes()).unwrap();

if let Err(e) = stream.write_all(contents) {
    println!("Error: {:?}", e)
}
stream.flush().unwrap();

Simple html file can be served without any issue, but a mkv file of 2GB would incur the error: Error: Os { code: 22, kind: InvalidInput, message: "Invalid argument" }

so it didn't write a single byte to the client: 2021-06-27 16:41:57 (0,00 B/s) - Connection closed at byte 0. Retrying.

The InvalidInput kind of confuses me, as far as I can see, the contents is &[u8] for sure, what could be possible for this?

But I think this error for write(2) system call is that:

EINVAL  fd is attached to an object which is unsuitable for 
        writing; or the file was opened with the O_DIRECT flag, and
        either  the  address  specified  in  buf,  the value 
        specified in count, or thefile offset is not suitably 
        aligned.

Thanks!

Upvotes: 2

Views: 1246

Answers (1)

rostamn739
rostamn739

Reputation: 421

See linux write(2) man page https://man7.org/linux/man-pages/man2/write.2.html

On Linux, write() (and similar system calls) will transfer at most 0x7ffff000 (2,147,479,552) bytes, returning the number of bytes actually transferred. (This is true on both 32-bit and 64-bit systems.)

Upvotes: 1

Related Questions