2020-11-16 10:59:37 +03:00
|
|
|
import io
|
|
|
|
import net
|
|
|
|
import strings
|
|
|
|
|
|
|
|
const (
|
2021-06-13 23:53:38 +03:00
|
|
|
server_port = ':22443'
|
2020-11-16 10:59:37 +03:00
|
|
|
)
|
|
|
|
|
2021-06-13 23:53:38 +03:00
|
|
|
fn accept(mut server net.TcpListener, c chan &net.TcpConn) {
|
|
|
|
c <- server.accept() or { panic(err) }
|
|
|
|
}
|
|
|
|
|
2021-01-20 13:11:01 +03:00
|
|
|
fn setup() (&net.TcpListener, &net.TcpConn, &net.TcpConn) {
|
2021-06-13 23:53:38 +03:00
|
|
|
mut server := net.listen_tcp(.ip6, server_port) or { panic(err) }
|
|
|
|
|
|
|
|
c := chan &net.TcpConn{}
|
|
|
|
go accept(mut server, c)
|
|
|
|
mut client := net.dial_tcp('localhost$server_port') or { panic(err) }
|
|
|
|
|
|
|
|
socket := <-c
|
|
|
|
|
2020-11-16 10:59:37 +03:00
|
|
|
$if debug_peer_ip ? {
|
2021-06-13 23:53:38 +03:00
|
|
|
eprintln('$server.addr()\n$client.peer_addr(), $client.addr()\n$socket.peer_addr(), $socket.addr()')
|
2020-11-16 10:59:37 +03:00
|
|
|
}
|
|
|
|
assert true
|
|
|
|
return server, client, socket
|
|
|
|
}
|
|
|
|
|
2021-01-20 13:11:01 +03:00
|
|
|
fn cleanup(mut server net.TcpListener, mut client net.TcpConn, mut socket net.TcpConn) {
|
2021-05-13 10:26:10 +03:00
|
|
|
server.close() or {}
|
|
|
|
client.close() or {}
|
|
|
|
socket.close() or {}
|
2020-11-16 10:59:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
fn test_socket() {
|
2021-01-20 13:11:01 +03:00
|
|
|
mut server, mut client, mut socket := setup()
|
2020-11-16 10:59:37 +03:00
|
|
|
defer {
|
2021-01-20 13:11:01 +03:00
|
|
|
cleanup(mut server, mut client, mut socket)
|
2020-11-16 10:59:37 +03:00
|
|
|
}
|
|
|
|
message := 'Hello World'
|
2021-03-20 19:25:51 +03:00
|
|
|
socket.write_string(message) or {
|
2020-11-16 10:59:37 +03:00
|
|
|
assert false
|
|
|
|
return
|
|
|
|
}
|
|
|
|
assert true
|
|
|
|
$if debug {
|
|
|
|
println('message send: $message')
|
|
|
|
}
|
|
|
|
$if debug {
|
|
|
|
println('send socket: $socket.sock.handle')
|
|
|
|
}
|
2022-04-15 15:35:35 +03:00
|
|
|
mut buf := []u8{len: 1024}
|
2020-11-16 10:59:37 +03:00
|
|
|
nbytes := client.read(mut buf) or {
|
|
|
|
assert false
|
|
|
|
return
|
|
|
|
}
|
|
|
|
received := buf[0..nbytes].bytestr()
|
|
|
|
$if debug {
|
|
|
|
println('message received: $received')
|
|
|
|
}
|
|
|
|
$if debug {
|
|
|
|
println('client: $client.sock.handle')
|
|
|
|
}
|
|
|
|
assert message == received
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test_socket_write_and_read() {
|
2021-01-20 13:11:01 +03:00
|
|
|
mut server, mut client, mut socket := setup()
|
2020-11-16 10:59:37 +03:00
|
|
|
defer {
|
2021-01-20 13:11:01 +03:00
|
|
|
cleanup(mut server, mut client, mut socket)
|
2020-11-16 10:59:37 +03:00
|
|
|
}
|
|
|
|
message1 := 'a message 1'
|
2021-03-20 19:25:51 +03:00
|
|
|
socket.write_string(message1) or { assert false }
|
2022-04-15 15:35:35 +03:00
|
|
|
mut rbuf := []u8{len: message1.len}
|
2021-01-26 17:43:10 +03:00
|
|
|
client.read(mut rbuf) or {
|
|
|
|
assert false
|
|
|
|
return
|
|
|
|
}
|
2020-11-16 10:59:37 +03:00
|
|
|
line := rbuf.bytestr()
|
|
|
|
assert line == message1
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test_socket_read_line() {
|
2021-01-20 13:11:01 +03:00
|
|
|
mut server, mut client, mut socket := setup()
|
2021-05-13 10:26:10 +03:00
|
|
|
mut reader := io.new_buffered_reader(reader: client)
|
2020-11-16 10:59:37 +03:00
|
|
|
defer {
|
2021-01-20 13:11:01 +03:00
|
|
|
cleanup(mut server, mut client, mut socket)
|
2020-11-16 10:59:37 +03:00
|
|
|
}
|
|
|
|
message1, message2 := 'message1', 'message2'
|
|
|
|
message := '$message1\n$message2\n'
|
2021-03-20 19:25:51 +03:00
|
|
|
socket.write_string(message) or { assert false }
|
2020-11-16 10:59:37 +03:00
|
|
|
assert true
|
|
|
|
//
|
|
|
|
line1 := reader.read_line() or {
|
|
|
|
// println(reader.buf)
|
|
|
|
assert false
|
|
|
|
return
|
|
|
|
}
|
|
|
|
line2 := reader.read_line() or {
|
|
|
|
// println(reader.buf)
|
|
|
|
assert false
|
|
|
|
return
|
|
|
|
}
|
|
|
|
assert line1 == message1
|
|
|
|
assert line2 == message2
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test_socket_write_fail_without_panic() {
|
2021-01-20 13:11:01 +03:00
|
|
|
mut server, mut client, mut socket := setup()
|
2020-11-16 10:59:37 +03:00
|
|
|
defer {
|
2021-01-20 13:11:01 +03:00
|
|
|
cleanup(mut server, mut client, mut socket)
|
2020-11-16 10:59:37 +03:00
|
|
|
}
|
|
|
|
message2 := 'a message 2'
|
|
|
|
// ensure that socket.write (i.e. done on the server side)
|
|
|
|
// continues to work, even when the client side has been disconnected
|
|
|
|
// this test is important for a stable long standing server
|
2021-05-13 10:26:10 +03:00
|
|
|
client.close() or {}
|
2020-11-16 10:59:37 +03:00
|
|
|
$if solaris {
|
|
|
|
return
|
|
|
|
}
|
2021-09-23 13:48:41 +03:00
|
|
|
$if freebsd {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
// TODO: fix segfaulting on Solaris and FreeBSD
|
2020-11-16 10:59:37 +03:00
|
|
|
for i := 0; i < 3; i++ {
|
2021-03-20 19:25:51 +03:00
|
|
|
socket.write_string(message2) or {
|
2020-11-16 10:59:37 +03:00
|
|
|
println('write to a socket without a recipient should produce an option fail: $err | $message2')
|
|
|
|
assert true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-11-20 17:24:41 +03:00
|
|
|
|
|
|
|
fn test_socket_read_line_long_line_without_eol() {
|
2021-01-20 13:11:01 +03:00
|
|
|
mut server, mut client, mut socket := setup()
|
2021-05-13 10:26:10 +03:00
|
|
|
mut reader := io.new_buffered_reader(reader: client)
|
2020-11-20 17:24:41 +03:00
|
|
|
defer {
|
2021-01-20 13:11:01 +03:00
|
|
|
cleanup(mut server, mut client, mut socket)
|
2020-11-20 17:24:41 +03:00
|
|
|
}
|
|
|
|
message := strings.repeat_string('123', 400)
|
2021-03-20 19:25:51 +03:00
|
|
|
socket.write_string(message) or {
|
2021-01-26 17:43:10 +03:00
|
|
|
assert false
|
|
|
|
return
|
|
|
|
}
|
2021-03-20 19:25:51 +03:00
|
|
|
socket.write_string('\n') or {
|
2021-01-26 17:43:10 +03:00
|
|
|
assert false
|
|
|
|
return
|
|
|
|
}
|
2020-11-20 17:24:41 +03:00
|
|
|
line := reader.read_line() or {
|
|
|
|
assert false
|
|
|
|
return
|
|
|
|
}
|
|
|
|
assert line == message
|
|
|
|
}
|