1 | // vtest flaky: true |
2 | // vtest retry: 8 |
3 | import net |
4 | import os |
5 | |
6 | const ( |
7 | test_port = 45123 |
8 | ) |
9 | |
10 | fn handle_conn(mut c net.TcpConn) { |
11 | for { |
12 | mut buf := []u8{len: 100, init: 0} |
13 | read := c.read(mut buf) or { |
14 | println('Server: connection dropped') |
15 | return |
16 | } |
17 | c.write(buf[..read]) or { |
18 | println('Server: connection dropped') |
19 | return |
20 | } |
21 | } |
22 | } |
23 | |
24 | fn one_shot_echo_server(mut l net.TcpListener, ch_started chan int) ? { |
25 | eprintln('> one_shot_echo_server') |
26 | ch_started <- 1 |
27 | mut new_conn := l.accept() or { return error('could not accept') } |
28 | eprintln(' > new_conn: ${new_conn}') |
29 | handle_conn(mut new_conn) |
30 | new_conn.close() or {} |
31 | } |
32 | |
33 | fn echo(address string) ! { |
34 | mut c := net.dial_tcp(address)! |
35 | defer { |
36 | c.close() or {} |
37 | } |
38 | |
39 | println('local: ' + c.addr()!.str()) |
40 | println(' peer: ' + c.peer_addr()!.str()) |
41 | |
42 | data := 'Hello from vlib/net!' |
43 | c.write_string(data)! |
44 | mut buf := []u8{len: 4096} |
45 | read := c.read(mut buf) or { panic(err) } |
46 | assert read == data.len |
47 | for i := 0; i < read; i++ { |
48 | assert buf[i] == data[i] |
49 | } |
50 | println('Got "${buf.bytestr()}"') |
51 | } |
52 | |
53 | fn test_tcp_ip6() { |
54 | eprintln('\n>>> ${@FN}') |
55 | address := 'localhost:${test_port}' |
56 | mut l := net.listen_tcp(.ip6, ':${test_port}') or { panic(err) } |
57 | dump(l) |
58 | start_echo_server(mut l) |
59 | echo(address) or { panic(err) } |
60 | l.close() or {} |
61 | // ensure there is at least one new socket created before the next test |
62 | l = net.listen_tcp(.ip6, ':${test_port + 1}') or { panic(err) } |
63 | } |
64 | |
65 | fn start_echo_server(mut l net.TcpListener) { |
66 | ch_server_started := chan int{} |
67 | spawn one_shot_echo_server(mut l, ch_server_started) |
68 | _ := <-ch_server_started |
69 | } |
70 | |
71 | fn test_tcp_ip() { |
72 | eprintln('\n>>> ${@FN}') |
73 | address := 'localhost:${test_port}' |
74 | mut l := net.listen_tcp(.ip, address) or { panic(err) } |
75 | dump(l) |
76 | start_echo_server(mut l) |
77 | echo(address) or { panic(err) } |
78 | l.close() or {} |
79 | } |
80 | |
81 | fn test_tcp_unix() { |
82 | eprintln('\n>>> ${@FN}') |
83 | // TODO(emily): |
84 | // whilst windows supposedly supports unix sockets |
85 | // this doesnt work (wsaeopnotsupp at the call to bind()) |
86 | $if !windows { |
87 | address := os.real_path('tcp-test.sock') |
88 | // address := 'tcp-test.sock' |
89 | println('${address}') |
90 | |
91 | mut l := net.listen_tcp(.unix, address) or { panic(err) } |
92 | start_echo_server(mut l) |
93 | echo(address) or { panic(err) } |
94 | l.close() or {} |
95 | |
96 | os.rm(address) or { panic('failed to remove socket file') } |
97 | } |
98 | } |
99 | |
100 | fn testsuite_end() { |
101 | eprintln('\ndone') |
102 | } |
103 | |
104 | fn test_bind() { |
105 | $if !network ? { |
106 | return |
107 | } |
108 | mut conn := net.dial_tcp_with_bind('vlang.io:80', '127.0.0.1:0')! |
109 | conn.close()! |
110 | } |