Tcp listener and stream on same port


#1

I am writing an integration test where I spawn two processes, a tcp listener and a sender. I am using TcpStream to send a message to the TcpListener. It doesn’t work because both processes are trying to use the same port.

How do I solve this problem?

thread ‘main’ panicked at ‘called Result::unwrap() on an Err value: Os { code: 98, kind: AddrInUse, message: “Address already in use” }’, libcore/result.rs:945:5
note: Run with RUST_BACKTRACE=1 for a backtrace.

test code

#[test]
fn say_hello() {
let mut listener = Command::new("./target/debug/teleport")
.arg(“8080”)
.arg(“listen”)
.stdout(Stdio::piped())
.spawn()
.expect(“failed to execute child”);

let mut sender = Command::new("./target/debug/teleport")
    .arg("8080")
    .arg("send")
    .spawn()
    .expect("failed to execute child");

let mut s = String::new();
match listener.stdout.unwrap().read_to_string(&mut s) {
     Err(why) => panic!("couldn't read wc stdout: {}",
                       why.description()),
     Ok(_) => print!("wc responded with:\n{}", s),

}
assert_eq!(s, "Goodbye")

}


#2

You mean they’re both trying to listen on the same port? It looks like your “sender” is started in a “send” mode, which implies (without knowing your code) that it should only be connecting to the port and not listening on it.

Anyway, my guess is actually that 8080 is already being used by a different process altogether (or maybe another instance of your listener). Do you have other tests (that get run alongside this one) that start a listener on 8080?


#3

Thanks for your response vitaly

I am pretty sure I am not starting two listeners but I will have a deeper look. There are no other processes running, I have tried many ports and i get the same result. That is my only test that starts a process

edit: I found a mistake in command line parsing that was causing the program to always start as a listener rather than a connection


#4

Right - I was about to comment on the “sender” vs “send” discrepancy there. Make sure your cmdline parsing is strict - don’t default _ => None there.