1package main
2
3import "core:fmt"
4import "core:net"
5import "core:thread"
6
7is_ctrl_d :: proc(bytes: []u8) -> bool {
8 return len(bytes) == 1 && bytes[0] == 4
9}
10
11is_empty :: proc(bytes: []u8) -> bool {
12 return(
13 (len(bytes) == 2 && bytes[0] == '\r' && bytes[1] == '\n') ||
14 (len(bytes) == 1 && bytes[0] == '\n') \
15 )
16}
17
18is_telnet_ctrl_c :: proc(bytes: []u8) -> bool {
19 return(
20 (len(bytes) == 3 && bytes[0] == 255 && bytes[1] == 251 && bytes[2] == 6) ||
21 (len(bytes) == 5 &&
22 bytes[0] == 255 &&
23 bytes[1] == 244 &&
24 bytes[2] == 255 &&
25 bytes[3] == 253 &&
26 bytes[4] == 6) \
27 )
28}
29
30handle_msg :: proc(sock: net.TCP_Socket) {
31 buffer: [256]u8
32 for {
33 bytes_recv, err_recv := net.recv_tcp(sock, buffer[:])
34 if err_recv != nil {
35 fmt.println("Failed to receive data")
36 }
37 received := buffer[:bytes_recv]
38 if len(received) == 0 ||
39 is_ctrl_d(received) ||
40 is_empty(received) ||
41 is_telnet_ctrl_c(received) {
42 fmt.println("Disconnecting client")
43 break
44 }
45 fmt.printfln("Server received [ %d bytes ]: %s", len(received), received)
46 bytes_sent, err_send := net.send_tcp(sock, received)
47 if err_send != nil {
48 fmt.println("Failed to send data")
49 }
50 sent := received[:bytes_sent]
51 fmt.printfln("Server sent [ %d bytes ]: %s", len(sent), sent)
52 }
53 net.close(sock)
54}
55
56tcp_echo_server :: proc(ip: string, port: int) {
57 local_addr, ok := net.parse_ip4_address(ip)
58 if !ok {
59 fmt.println("Failed to parse IP address")
60 return
61 }
62 endpoint := net.Endpoint {
63 address = local_addr,
64 port = port,
65 }
66 sock, err := net.listen_tcp(endpoint)
67 if err != nil {
68 fmt.println("Failed to listen on TCP")
69 return
70 }
71 fmt.printfln("Listening on TCP: %s", net.endpoint_to_string(endpoint))
72 for {
73 cli, _, err_accept := net.accept_tcp(sock)
74 if err_accept != nil {
75 fmt.println("Failed to accept TCP connection")
76 continue
77 }
78 thread.create_and_start_with_poly_data(cli, handle_msg)
79 }
80 net.close(sock)
81 fmt.println("Closed socket")
82}
83
84main :: proc() {
85 tcp_echo_server("127.0.0.1", 8080)
86}