Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple TCP server #9626

Closed
simao opened this issue Sep 30, 2013 · 5 comments
Closed

Simple TCP server #9626

simao opened this issue Sep 30, 2013 · 5 comments

Comments

@simao
Copy link

simao commented Sep 30, 2013

Hello,

I am trying to start a TCP listener using the following code:

use std::rt::io::net::tcp::TcpListener;
use std::rt::io::{Reader, Writer, Listener, Acceptor};
use std::rt::io::net::ip::{SocketAddr, Ipv4Addr};
use std::vec;
use std::str;

fn main() {
    let addr = SocketAddr {
        ip: Ipv4Addr(0, 0, 0, 0),
        port: 9090
    };

    let mut acceptor = TcpListener::bind(addr).listen().unwrap();

    println("Listener is ready");

    loop {
        let mut stream = acceptor.accept().unwrap();
        let mut buf = vec::from_elem(1, 0u8); // Use just 1 byte to debug

        loop {
            match stream.read(buf) {
                Some(count) => {
                    if count > 0 {
                        print(str::from_utf8(buf));
                    } else {
                        println("GOT NOTHING");
                        break;
                    }
                }
                None => { println("Finished"); break }
            }
        }

        stream.write(bytes!("Hello World\r\n"));

        //        println(str::from_utf8(buf));

    }
}

So the problem here is that after the server reads all the data from
the client and then it blocks on the next read waiting for more
data, while the client, in this case curl will not send any more
data.

I tried to use stream.eof but this function is not implemented and
just throws an exception.

What is the recommended way to do this while stream.eof is not
implemented?

Thank you

@bmaxa
Copy link

bmaxa commented Sep 30, 2013

Here is example of simple TCP server that will give you idea how to write
yours. Server spawns lightweight thread on new connection
and handles read/write in there so you could handle xxx connections
simultaneously. Eof is when stream.read() functions return None.
This server closes connection after single read, so you can
test eg with a(pache)b(ench) or something.

use std::rt::io::net::tcp::TcpListener;
use std::rt::io::{Reader, Writer, Listener, Acceptor};
use std::rt::io::net::ip::{SocketAddr, Ipv4Addr};
use std::str;
use std::cell::Cell;

fn main() {
    let addr = SocketAddr {
        ip: Ipv4Addr(0, 0, 0, 0),
        port: 9090
    };

    let mut acceptor = TcpListener::bind(addr).listen().unwrap();

    println("Listener is ready");

    loop {
        let stream = acceptor.accept().unwrap();
        let stream = Cell::new(stream);
        do spawn{
            let mut buf = [0,..512];
            let mut stream = stream.take();
            loop {
                match stream.read(buf) {
                    Some(count) => {
                        print("read "+count.to_str()+" bytes: "+str::from_utf8(buf));
                        stream.write(bytes!("Hello World\r\n"));
                        break; // close connection after read
                    }
                    None => { println("Finished"); break } // connection is closed by client
                }
            }

        }

    }
}

@simao
Copy link
Author

simao commented Sep 30, 2013

Hello,

This code has the same problem as mine.

If you change the size of the buffer to a small value, like [0,..1], emulating a big request from the client, the server needs to loop in order to call .read multiple times before closing the connection.

On the last .read, when the client already sent the complete request, the server will block forever waiting for more data from the client, and never close the connection. This could be avoided if we could call .eof before calling .read again, but .eof is not yet implemented in tcp.rs.

Thanks!

@bmaxa
Copy link

bmaxa commented Sep 30, 2013

Eof will not help, as it will never trigger if client does not closes connection (and we know
already if client closes, read returns None).
So problem is that you have to know when to stop reading and start writing,
and that's a matter of protocol.

@simao
Copy link
Author

simao commented Sep 30, 2013

Ah I see! Thank you for your help!

@alexcrichton
Copy link
Member

Closing because I agree that this is a protocol thing and not a rt::io thing.

bors added a commit to rust-lang-ci/rust that referenced this issue Jul 25, 2022
…ion-in-vscode-settings, r=Veykril

feat: Support variable substitution in VSCode settings

Currently support a subset of [variables provided by VSCode](https://code.visualstudio.com/docs/editor/variables-reference) in `server.extraEnv` section of Rust-Analyzer settings:

  * `workspaceFolder`
  * `workspaceFolderBasename`
  * `cwd`
  * `execPath`
  * `pathSeparator`

Also, this PR adds support for general environment variables resolution. You can declare environment variables and reference them from other variables like this:

```JSON
"rust-analyzer.server.extraEnv": {
    "RUSTFLAGS": "-L${env:OPEN_XR_SDK_PATH}",
    "OPEN_XR_SDK_PATH": "${workspaceFolder}\\..\\OpenXR-SDK\\build\\src\\loader\\Release"
},
```
The order of variable declaration doesn't matter, you can reference variables before defining them. If the variable is not present in `extraEnv` section, VSCode will search for them in your environment. Missing variables will be replaced with empty string. Circular references won't be resolved and will be passed to rust-analyzer server process as is.

Closes rust-lang#9626, but doesn't address use cases where people want to use values provided by `rustc` or `cargo`, such as `${targetTriple}` proposal rust-lang#11649
flip1995 pushed a commit to flip1995/rust that referenced this issue Oct 18, 2024
…r=Manishearth

Compare trait references in `trait_duplication_in_bounds` correctly

Fixes rust-lang#13476
Fixes rust-lang#11067
Fixes rust-lang#9915
Fixes rust-lang#9626

Currently, the `trait_duplication_in_bounds` lints has a helper type for a trait reference that can be used for comparison and hashing, represented as `{trait: Res, generic_args: Vec<Res>}`. However, there are a lot of issues with this. For one, a `Res` can't represent e.g. references, slices, or lots of other types, as well as const generics and associated type equality. In those cases, the lint simply ignores them and has no way of checking if they're actually the same.

So, instead of using `Res` for this, use `SpanlessEq` and `SpanlessHash` for comparisons with the trait path for checking if there are duplicates.

However, using `SpanlessEq` as is alone lead to a false negative in the test. `std::clone::Clone` + `foo::Clone` wasn't recognized as a duplicate, because it has different segments. So this also adds a new "mode" to SpanlessEq which compares by final resolution. (I've been wondering if this can't just be the default but it's quite a large scale change as it affects a lot of lints and I haven't yet looked at all uses of it to see if there are lints that really do care about having exactly the same path segments).

Maybe an alternative would be to turn the hir types/consts into middle types/consts and compare them instead but I'm not sure there's really a good way to do that

changelog: none
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants