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.