Hi, just wanted to find some help, related to TCP in the new API, I wanted to play a bit with it to get more familiar with how it changed to upgrade a project of mine later, but I’m stuck at something, and I’m not sure what I’m doing wrong here.
const std = @import("std");
const mem = std.mem;
const Io = std.Io;
const heap = std.heap;
const net = std.net;
const proc = std.process;
pub const Options = struct {
    address: net.Address,
    pub fn init(args: *proc.ArgIterator) Options {
        var result: Options = .{
            .address = net.Address.initIp4([4]u8{ 127, 0, 0, 1 }, 0),
        };
        while (args.next()) |arg| {
            if (mem.startsWith(u8, arg, "--address=")) {
                result.address = net.Address.parseIpAndPort(arg[mem.indexOf(u8, arg, "=").? + 1 ..]) catch |err| {
                    std.log.warn("Failed to parse provided network address : {}", .{err});
                    return result;
                };
            }
        }
        return result;
    }
};
pub const HeartBeat = struct {
    timer: std.time.Timer,
    tickrate_hz: f32 = 1,
    frequency: usize = 0,
    acc: usize,
    pub fn init(comptime tickrate_hz: f32) HeartBeat {
        return .{
            .timer = std.time.Timer.start() catch unreachable,
            .tickrate_hz = tickrate_hz,
            .frequency = @intFromFloat(@divFloor(@as(f32, 1_000_000_000.0), tickrate_hz)),
            .acc = 0,
        };
    }
    pub fn tick(self: *HeartBeat) bool {
        if (self.acc >= self.frequency) {
            self.acc = 0;
            return true;
        } else {
            self.acc += self.timer.lap();
            return false;
        }
    }
};
var stop: bool = false;
pub fn mockClient(args: net.Address) void {
    var read_buffer: [4096]u8 = undefined;
    var write_buffer: [4096]u8 = undefined;
    var conn: net.Stream = undefined;
    while (true) {
        conn = net.tcpConnectToAddress(args) catch continue;
        break;
    }
    var stream_reader = conn.reader(&read_buffer).file_reader.interface;
    var stdout_writer = std.fs.File.stdout().writer(&write_buffer);
    var stdout = &stdout_writer.interface;
    while (!stop) {
        _ = stream_reader.stream(stdout, .limited(stdout.buffer.len)) catch unreachable;
        stdout.print("{s}", .{stdout.buffered()}) catch unreachable;
    }
}
pub fn main() !void {
    var gpa_instance: heap.GeneralPurposeAllocator(.{}) = .init;
    defer _ = gpa_instance.deinit();
    const gpa = gpa_instance.allocator();
    var args = std.process.argsWithAllocator(gpa) catch |err| {
        std.log.err("Encountered fatal error : {}", .{err});
        return;
    };
    defer args.deinit();
    var options: Options = .init(&args);
    var server: net.Server = options.address.listen(.{ .reuse_address = true }) catch |err| {
        std.log.err("Encountered fatal error : {}", .{err});
        return;
    };
    server.deinit();
    var heart_beat: HeartBeat = .init(0.5);
    var i: usize = 0;
    var client: ?net.Stream = null;
    var write_buffer: [4096]u8 = undefined;
    var thread = std.Thread.spawn(.{}, mockClient, .{options.address}) catch unreachable;
    defer thread.join();
    while (!stop) {
        if (heart_beat.tick()) {
            std.debug.print("{f}\n", .{options.address});
            i += 1;
        }
        if (client == null) {
            const conn = server.accept() catch |err| {
                std.log.err("Encountered error : {}", .{err});
                continue;
            };
            client = conn.stream;
        }
        if (client) |active| {
            var client_writer = active.writer(&write_buffer);
            var cw = &client_writer.interface;
            try cw.print("Hello World\n", .{});
            try cw.flush();
        }
        if (i == 10) {
            stop = true;
        }
    }
}
First of all I’m not sure I’m using the Api correctly for the Io part, and second the accept is failing and I don’t know why exactly.
src ) zbr
thread 27244 panic: reached unreachable code
/home/pollivie/.local/share/zigup/0.15.1/files/lib/std/posix.zig:3974:26: 0x115a58b in accept (std.zig)
                .BADF => unreachable, // always a race condition
                         ^
/home/pollivie/.local/share/zigup/0.15.1/files/lib/std/net.zig:2411:36: 0x1152818 in accept (std.zig)
        const fd = try posix.accept(s.stream.handle, &accepted_addr.any, &addr_len, posix.SOCK.CLOEXEC);
                                   ^
/home/pollivie/workspace/pi_server/src/main.zig:108:39: 0x114da30 in main (main.zig)
            const conn = server.accept() catch |err| {
                                      ^
/home/pollivie/.local/share/zigup/0.15.1/files/lib/std/start.zig:627:37: 0x114e9c9 in posixCallMainAndExit (std.zig)
            const result = root.main() catch |err| {
                                    ^
/home/pollivie/.local/share/zigup/0.15.1/files/lib/std/start.zig:232:5: 0x114d331 in _start (std.zig)
    asm volatile (switch (native_arch) {
    ^
???:?:?: 0x0 in ??? (???)
run
└─ run exe pi_server failure
error: the following command terminated unexpectedly:
/home/pollivie/workspace/pi_server/zig-out/bin/pi_server
I’m not sure what the issue is honestly, it seems like accept is falling on BADF which I don’t really know the meaning of since I think I’m listening/opening the socket correctly, so I must be doing something obviously wrong here, but can’t figure it out.