You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/intro.md
+2
Original file line number
Diff line number
Diff line change
@@ -60,6 +60,7 @@ community. It needs and welcomes help. For details see
60
60
|[Query the GitHub API][ex-rest-get]|[![reqwest-badge]][reqwest][![serde-badge]][serde]|[![cat-net-badge]][cat-net][![cat-encoding-badge]][cat-encoding]|
61
61
|[Check if an API Resource Exists][ex-rest-head]|[![reqwest-badge]][reqwest]|[![cat-net-badge]][cat-net]|
62
62
|[Create and delete Gist with GitHub API][ex-rest-post]|[![reqwest-badge]][reqwest][![serde-badge]][serde]|[![cat-net-badge]][cat-net][![cat-encoding-badge]][cat-encoding]|
63
+
|[Listen on Unused port TCP/IP][ex-random-port-tcp]|[![std-badge]][std]|[![cat-net-badge]][cat-net]|
Copy file name to clipboardExpand all lines: src/net.md
+64
Original file line number
Diff line number
Diff line change
@@ -12,6 +12,7 @@
12
12
|[Query the GitHub API][ex-rest-get]|[![reqwest-badge]][reqwest][![serde-badge]][serde]|[![cat-net-badge]][cat-net][![cat-encoding-badge]][cat-encoding]|
13
13
|[Check if an API Resource Exists][ex-rest-head]|[![reqwest-badge]][reqwest]|[![cat-net-badge]][cat-net]|
14
14
|[Create and delete Gist with GitHub API][ex-rest-post]|[![reqwest-badge]][reqwest][![serde-badge]][serde]|[![cat-net-badge]][cat-net][![cat-encoding-badge]][cat-encoding]|
15
+
|[Listen on Unused port TCP/IP][ex-random-port-tcp]|[![std-badge]][std]|[![cat-net-badge]][cat-net]|
15
16
16
17
[ex-url-parse]: #ex-url-parse
17
18
<aname="ex-url-parse"/>
@@ -528,6 +529,61 @@ fn run() -> Result<()> {
528
529
# quick_main!(run);
529
530
```
530
531
532
+
[ex-random-port-tcp]: #ex-random-port-tcp
533
+
<aname="ex-random-port-tcp"></a>
534
+
## Listen on Unused port TCP/IP
535
+
536
+
[![std-badge]][std][![cat-net-badge]][cat-net]
537
+
538
+
In this example, the port is displayed on the console, and the program will
539
+
listen until a request is made.
540
+
541
+
```rust, no_run
542
+
#[macro_use]
543
+
extern crate error_chain;
544
+
545
+
use std::net::{SocketAddrV4, Ipv4Addr, TcpListener};
546
+
use std::io::Read;
547
+
548
+
error_chain! {
549
+
foreign_links {
550
+
Io(::std::io::Error);
551
+
}
552
+
}
553
+
554
+
fn run() -> Result<()> {
555
+
let loopback = Ipv4Addr::new(127, 0, 0, 1);
556
+
// Assigning port 0 requests the OS to assign a free port
557
+
let socket = SocketAddrV4::new(loopback, 0);
558
+
let listener = TcpListener::bind(socket)?;
559
+
let port = listener.local_addr()?;
560
+
println!("Listening on {}, access this port to end the program", port);
561
+
let (mut tcp_stream, addr) = listener.accept()?; //block until requested
562
+
println!("Connection received! {:?} is sending data.", addr);
563
+
let mut input = String::new();
564
+
// read from the socket until connection closed by client, discard byte count.
565
+
let _ = tcp_stream.read_to_string(&mut input)?;
566
+
println!("{:?} says {}", addr, input);
567
+
Ok(())
568
+
}
569
+
570
+
quick_main!(run);
571
+
```
572
+
573
+
The `std` library is leveraged to make a well formed IP/port with the
574
+
[`SocketAddrV4`] and [`Ipv4Addr`] structs. An unused random port is requested
575
+
by passing 0 to [`TcpListener::bind`]. The assigned address is available via
576
+
[`TcpListener::local_addr`].
577
+
578
+
[`TcpListener::accept`] synchronously waits for an incoming connection and
579
+
returns a `(`[`TcpStream`], [`SocketAddrV4`]`)` representing the request.
580
+
Reading on the socket with [`read_to_string`] will wait until the connection is
581
+
closed which can be tested with `telnet ip port`. For example, if the program
582
+
shows Listening on 127.0.0.1:11500, run
583
+
584
+
`telnet 127.0.0.1 11500`
585
+
586
+
After sending data in telnet press `ctrl-]` and type `quit`.
0 commit comments