Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
i4
manycore
emper-io-eval
Commits
9416a3d4
Commit
9416a3d4
authored
Nov 29, 2021
by
Florian Fischer
Browse files
[go/tokio] set SO_REUSE{ADDR,PORT} sockopts
And format both.
parent
96f291b7
Pipeline
#72965
passed with stage
in 2 minutes and 1 second
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
servers/go-echo-server/echo.go
View file @
9416a3d4
package
main
import
(
"context"
"flag"
"log"
"net"
"os"
"strconv"
"syscall"
"time"
)
// Taken from https://pkg.go.dev/golang.org/x/sys/unix#pkg-constants
const
(
SOL_SOCKET
=
0x1
SO_REUSEADDR
=
0x2
SO_REUSEPORT
=
0xf
)
func
main
()
{
port
:=
flag
.
Int
(
"port"
,
12345
,
"Port to accept connections on."
)
host
:=
flag
.
String
(
"host"
,
"0.0.0.0"
,
"Host or IP to bind to"
)
computation
:=
flag
.
Uint
(
"computation"
,
0
,
"Computation done before sending a responce in microseconds"
)
flag
.
Parse
()
l
,
err
:=
net
.
Listen
(
"tcp"
,
*
host
+
":"
+
strconv
.
Itoa
(
*
port
))
lc
:=
net
.
ListenConfig
{
Control
:
func
(
network
,
address
string
,
conn
syscall
.
RawConn
)
error
{
var
operr
error
err
:=
conn
.
Control
(
func
(
fd
uintptr
)
{
operr
=
syscall
.
SetsockoptInt
(
int
(
fd
),
SOL_SOCKET
,
SO_REUSEADDR
,
1
)
if
operr
!=
nil
{
return
}
operr
=
syscall
.
SetsockoptInt
(
int
(
fd
),
SOL_SOCKET
,
SO_REUSEPORT
,
1
)
})
if
err
!=
nil
{
return
err
}
return
operr
},
}
l
,
err
:=
lc
.
Listen
(
context
.
Background
(),
"tcp"
,
*
host
+
":"
+
strconv
.
Itoa
(
*
port
))
if
err
!=
nil
{
log
.
Panicln
(
err
)
}
log
.
Println
(
"Listening to connections at '"
+*
host
+
"' on port"
,
strconv
.
Itoa
(
*
port
),
"with"
,
*
computation
,
"microseconds computation"
)
defer
l
.
Close
()
...
...
servers/tokio-echo/Cargo.lock
View file @
9416a3d4
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "autocfg"
version = "1.0.1"
...
...
@@ -18,6 +20,12 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
version = "1.0.0"
...
...
@@ -39,7 +47,7 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d"
dependencies = [
"cfg-if",
"cfg-if
1.0.0
",
]
[[package]]
...
...
@@ -63,7 +71,7 @@ version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
"cfg-if
1.0.0
",
]
[[package]]
...
...
@@ -94,6 +102,17 @@ dependencies = [
"winapi",
]
[[package]]
name = "net2"
version = "0.2.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae"
dependencies = [
"cfg-if 0.1.10",
"libc",
"winapi",
]
[[package]]
name = "ntapi"
version = "0.3.6"
...
...
@@ -136,7 +155,7 @@ version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
dependencies = [
"cfg-if",
"cfg-if
1.0.0
",
"instant",
"libc",
"redox_syscall",
...
...
@@ -233,6 +252,7 @@ dependencies = [
name = "tokio-echo"
version = "0.1.0"
dependencies = [
"net2",
"tokio",
]
...
...
servers/tokio-echo/Cargo.toml
View file @
9416a3d4
...
...
@@ -6,3 +6,4 @@ edition = "2018"
[dependencies]
tokio
=
{
version
=
"1"
,
features
=
["full"]
}
net2
=
{
version
=
"0.2"
}
servers/tokio-echo/src/main.rs
View file @
9416a3d4
use
std
::
env
;
use
std
::
time
::{
Duration
,
Instant
};
use
tokio
::
net
::
TcpListener
;
use
tokio
::
io
::{
AsyncReadExt
,
AsyncWriteExt
};
use
tokio
::
net
::
TcpListener
;
extern
crate
net2
;
use
net2
::{
unix
::
UnixTcpBuilderExt
,
TcpBuilder
};
fn
main
()
->
Result
<
(),
Box
<
dyn
std
::
error
::
Error
>>
{
let
args
:
Vec
<
String
>
=
env
::
args
()
.collect
();
...
...
@@ -11,7 +15,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
2
=>
args
[
1
]
.parse
()
?
,
_
=>
{
_
=>
{
let
prog
=
&
args
[
0
];
panic!
(
"Usage: {} [computation in us]"
,
prog
);
}
...
...
@@ -28,43 +32,55 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
None
=>
{}
};
runtime_builder
.enable_all
()
.build
()
.unwrap
()
.block_on
(
async
{
let
listener
=
TcpListener
::
bind
(
"[::]:12345"
)
.await
.unwrap
();
println!
(
"Echoserver listening on :::12345 with {} microseconds computation"
,
computation
);
runtime_builder
.enable_all
()
.build
()
.unwrap
()
.block_on
(
async
{
let
std_listener
=
TcpBuilder
::
new_v6
()
?
.reuse_address
(
true
)
?
.reuse_port
(
true
)
?
.bind
(
"[::]:12345"
)
?
.listen
(
4096
)
?
;
let
listener
=
TcpListener
::
from_std
(
std_listener
)
.unwrap
();
println!
(
"Echoserver listening on :::12345 with {} microseconds computation"
,
computation
);
loop
{
let
(
mut
socket
,
_
)
=
listener
.accept
()
.await
.unwrap
();
loop
{
let
(
mut
socket
,
_
)
=
listener
.accept
()
.await
.unwrap
();
tokio
::
spawn
(
async
move
{
let
mut
buf
=
[
0
;
1024
];
tokio
::
spawn
(
async
move
{
let
mut
buf
=
[
0
;
1024
];
// In a loop, read data from the socket and write the data back.
loop
{
let
n
=
match
socket
.read
(
&
mut
buf
)
.await
{
// socket closed
Ok
(
n
)
if
n
==
0
=>
return
,
Ok
(
n
)
=>
n
,
Err
(
e
)
=>
{
eprintln!
(
"failed to read from socket; err = {:?}"
,
e
);
return
;
}
};
// In a loop, read data from the socket and write the data back.
loop
{
let
n
=
match
socket
.read
(
&
mut
buf
)
.await
{
// socket closed
Ok
(
n
)
if
n
==
0
=>
return
,
Ok
(
n
)
=>
n
,
Err
(
e
)
=>
{
eprintln!
(
"failed to read from socket; err = {:?}"
,
e
);
return
;
}
};
if
n
==
5
&&
&
buf
[
0
..
n
]
==
"quit
\n
"
.as_bytes
()
{
std
::
process
::
exit
(
0
);
}
if
n
==
5
&&
&
buf
[
0
..
n
]
==
"quit
\n
"
.as_bytes
()
{
std
::
process
::
exit
(
0
);
}
let
now
=
Instant
::
now
();
let
execution_duartion
=
Duration
::
from_micros
(
computation
);
while
now
.elapsed
()
<
execution_duartion
{}
let
now
=
Instant
::
now
();
let
execution_duartion
=
Duration
::
from_micros
(
computation
);
while
now
.elapsed
()
<
execution_duartion
{}
// Write the data back
if
let
Err
(
e
)
=
socket
.write_all
(
&
buf
[
0
..
n
])
.await
{
eprintln!
(
"failed to write to socket; err = {:?}"
,
e
);
return
;
// Write the data back
if
let
Err
(
e
)
=
socket
.write_all
(
&
buf
[
0
..
n
])
.await
{
eprintln!
(
"failed to write to socket; err = {:?}"
,
e
);
return
;
}
}
}
});
}
})
});
}
})
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment