This commit is contained in:
ge
2026-04-29 21:45:37 +03:00
parent e54f013ef7
commit 4ff0e46719
14 changed files with 1183 additions and 880 deletions
+22 -43
View File
@@ -1,55 +1,31 @@
import netio
fn main() {
// We want to bind a server socket to the all available local addresses,
// (both IPv4 and IPv6) so collect the address info entries for it.
ai := netio.addr_info(
service: '1081' // The port number to listen.
socktype: netio.sock_stream // Address must support TCP transport.
family: netio.af_inet6 // IPv6 support.
flags: netio.ai_passive // Passive mode for binding to any address (0.0.0.0, ::).
)!
// This is only for examples_test.v
is_test := '-test' in arguments()
// Just initialize variables.
mut socket := netio.Socket{}
mut listen_addr := netio.SocketAddr{}
// Create listen address.
listen_addr := netio.SocketAddr.new_ipv4([..]u8[127, 0, 0, 1], 1088)
// Create socket and bind to the first available address.
for a in ai {
// Create a socket with advertised parameters.
socket = netio.Socket.new(a.family, a.socktype, a.protocol)!
// Create server socket.
socket := netio.Socket.new(netio.af_inet, netio.sock_stream, 0)!
// Set SO_REUSEADDR enabled. It allows a server to bind to a port that
// is still in a `TIME-WAIT` state from a previous connection.
// https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Protocol_operation
socket.set_option(netio.sol_socket, netio.so_reuseaddr, 1)!
// Allow connections through IPv4, not only IPv6.
socket.set_option(netio.ipproto_ipv6, netio.ipv6_v6only, 0)!
// Bind socket to the address.
socket.bind(a.addr) or {
// Close previously created socket on bind error and continue with
// the next socket address.
socket.close()!
continue
}
// Set listen_addr.
listen_addr = a.addr
break
}
// If the socket.fd is -1 this means that we does not find any socket address.
if socket.fd == -1 {
eprintln('Cannot create socket...')
exit(1)
}
// Close the server socket on exit.
// Close server socket on exit.
defer {
socket.close() or { panic(err) }
}
// Set SO_REUSEADDR enabled. It allows a server to bind to a port that
// is still in a `TIME-WAIT` state from a previous connection.
// https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Protocol_operation
socket.set_option(netio.sol_socket, netio.so_reuseaddr, 1)!
// Bind socket to the address.
socket.bind(listen_addr) or {
eprintln('BIND: ${err}')
exit(1)
}
// Start listening for incoming connections on socket.
socket.listen(10) or {
eprintln('LISTEN: ${err}')
@@ -71,10 +47,13 @@ fn main() {
}
// Get remote host and port in numeric format.
remote_host, remote_port := netio.name_info(remote_addr,
remote_host, mut remote_port := netio.name_info(remote_addr,
flags: netio.ni_numerichost | netio.ni_numericserv
)!
if is_test {
remote_port = '1001'
}
eprintln('Accpeted connection. Remote address: ${remote_host}, remote port: ${remote_port}')
// Read 512 bytes of data from socket.