Karl Seguin started a new blog series at building a TCP server in Zig.
Part 1 - Single Threaded: TCP Server in Zig - Part 1 - Single Threaded
Part 2 - Message Boundaries: TCP Server in Zig - Part 2 - Message Boundaries
Part 3 - Minimizing Writes & Reads: TCP Server in Zig - Part 3 - Minimizing Writes & Reads
Part 4 - Multithreading: TCP Server in Zig - Part 4 - Multithreading
Part 5a - Poll: TCP Server in Zig - Part 5a - Poll
Part 5b - Poll: TCP Server in Zig - Part 5b - Poll
Part 6 - Epoll: TCP Server in Zig - Part 6 - Epoll
Part 7 - Kqueue: TCP Server in Zig - Part 7 - Kqueue
Part 8 - Epoll & Kqueue: TCP Server in Zig - Part 8 - Epoll & Kqueue
18 Likes
This is uncanny, I just came here (to ziggit) to ask for guidance on this exact topic. Thanks for sharing!
3 Likes
This is a really great series of posts. In part 5a you have got the following comment twice. The first time is a mistake, I believe.
// Oops, still have a +1 here, since we want to poll all our connected
// clients, plus our listening socket
There is also a small mistake when you introduce the removeClient
function (it is fixed in the code listing at the end of the article.
fn removeClient(self: *Server, at: usize) void {
posix.close(client.socket); // <- this needs to be below after the `var client....`
var client = self.clients[at];
client.deinit(self.allocator);
// Swap the client we're removing with the last one
// So that when we set connected -= 1, it'll effectively "remove"
// the client from our slices.
const last_index = self.connected - 1;
self.clients[at] = self.clients[last_index];
self.client_polls[at] = self.client_polls[last_index];
self.connected = last_index;
}