Skip to content

Instantly share code, notes, and snippets.

@lithdew
Last active July 18, 2020 09:53
Show Gist options
  • Save lithdew/b6680b9aff1cfd55699fad16014b636a to your computer and use it in GitHub Desktop.
Save lithdew/b6680b9aff1cfd55699fad16014b636a to your computer and use it in GitHub Desktop.
(wip) zig tcp server
const std = @import("std");
const print = std.debug.print;
const File = std.fs.File;
const BufferedWriter = std.io.BufferedWriter;
const Address = std.net.Address;
const Server = std.net.StreamServer;
const Connection = std.net.StreamServer.Connection;
const Allocator = std.mem.Allocator;
const ArenaAllocator = std.heap.ArenaAllocator;
pub const io_mode = .evented;
pub const PeerStack = std.atomic.Stack(*Peer);
pub const Peer = struct {
const Self = @This();
file: File,
writer: BufferedWriter(4096, File.Writer),
node: PeerStack.Node,
frame: @Frame(start),
address: Address,
pub fn init(allocator: *Allocator, file: File, address: Address) !*Self {
const peer = try allocator.create(Self);
errdefer allocator.destroy(peer);
peer.* = .{
.file = file,
.writer = .{ .unbuffered_writer = file.writer() },
.node = .{
.next = null,
.data = peer,
},
.frame = undefined,
.address = address,
};
return peer;
}
pub fn deinit(self: *Self) void {
self.file.close();
}
pub fn start(self: *Self) !void {
defer discard.push(&self.node);
print("{} connected.\n", .{self.address});
try self.writer.writer().writeAll("Hello world!\n");
try self.writer.flush();
}
};
var peers: std.event.Locked(std.ArrayList(anyframe)) = undefined;
var discard = PeerStack.init();
pub fn main() !void {
var arena = ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = &std.heap.loggingAllocator(&arena.allocator, std.io.getStdErr().writer()).allocator;
peers = std.event.Locked(std.ArrayList(anyframe)).init(std.ArrayList(anyframe).init(allocator));
var server = Server.init(.{});
defer server.close();
try server.listen(try Address.resolveIp("0.0.0.0", 9000));
while (true) {
const conn = server.accept() catch |err| {
print("Got error: {}\n", .{err});
break;
};
const peer = Peer.init(allocator, conn.file, conn.address) catch |err| {
conn.file.close();
continue;
};
peer.frame = async peer.start();
while (discard.pop()) |node| {
node.data.deinit();
allocator.destroy(node.data);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment