net/tcp_echo_server/server

Code

server.odin ¶
86 linesSource

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}

Declarations Used 12