Skip to content

Instantly share code, notes, and snippets.

@marijnfs
Forked from andrewrk/basic-tcp-chat.zig
Last active December 9, 2022 04:08
Show Gist options
  • Save marijnfs/78b0cc13d76a19dffbced766726189ec to your computer and use it in GitHub Desktop.
Save marijnfs/78b0cc13d76a19dffbced766726189ec to your computer and use it in GitHub Desktop.

Revisions

  1. marijnfs revised this gist Jul 18, 2021. 1 changed file with 7 additions and 7 deletions.
    14 changes: 7 additions & 7 deletions basic-tcp-chat.zig
    Original file line number Diff line number Diff line change
    @@ -32,10 +32,10 @@ const Client = struct {
    handle_frame: @Frame(handle),

    fn handle(self: *Client, room: *Room) !void {
    try self.conn.file.writeAll("server: welcome to teh chat server\n");
    _ = try self.conn.stream.write("server: welcome to teh chat server\n");
    while (true) {
    var buf: [100]u8 = undefined;
    const amt = try self.conn.file.read(&buf);
    const amt = try self.conn.stream.read(&buf);
    const msg = buf[0..amt];
    room.broadcast(msg, self);
    }
    @@ -45,11 +45,11 @@ const Room = struct {
    clients: std.AutoHashMap(*Client, void),

    fn broadcast(room: *Room, msg: []const u8, sender: *Client) void {
    var it = room.clients.iterator();
    while (it.next()) |entry| {
    const client = entry.key;
    var it = room.clients.keyIterator();
    while (it.next()) |key_ptr| {
    const client = key_ptr.*;
    if (client == sender) continue;
    client.conn.file.writeAll(msg) catch |e| std.debug.warn("unable to send: {}\n", .{e});
    _ = client.conn.stream.write(msg) catch |e| std.debug.warn("unable to send: {}\n", .{e});
    }
    }
    };
    };
  2. @andrewrk andrewrk revised this gist Aug 22, 2020. 2 changed files with 4 additions and 2 deletions.
    4 changes: 3 additions & 1 deletion basic-tcp-chat.zig
    Original file line number Diff line number Diff line change
    @@ -6,11 +6,13 @@ const os = std.os;
    pub const io_mode = .evented;

    pub fn main() anyerror!void {
    const allocator = std.heap.page_allocator; // TODO use a more appropriate allocator
    var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
    const allocator = &general_purpose_allocator.allocator;

    var server = net.StreamServer.init(.{});
    defer server.deinit();

    // TODO handle concurrent accesses to this hash map
    var room = Room{ .clients = std.AutoHashMap(*Client, void).init(allocator) };

    try server.listen(net.Address.parseIp("127.0.0.1", 0) catch unreachable);
    2 changes: 1 addition & 1 deletion instructions.txt
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    Tested with zig 0.5.0+f7f563ea5. The latest master branch build
    Tested with zig 0.6.0+4e63ca. The latest master branch build
    from https://ziglang.org/download/ should work just fine.

    zig build-exe basic-tcp-chat.zig
  3. @andrewrk andrewrk revised this gist Mar 26, 2020. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion instructions.txt
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,5 @@
    Tested with zig 0.5.0+f7f563ea5
    Tested with zig 0.5.0+f7f563ea5. The latest master branch build
    from https://ziglang.org/download/ should work just fine.

    zig build-exe basic-tcp-chat.zig
    ./basic-tcp-chat
  4. @andrewrk andrewrk created this gist Mar 26, 2020.
    53 changes: 53 additions & 0 deletions basic-tcp-chat.zig
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,53 @@
    const std = @import("std");
    const net = std.net;
    const fs = std.fs;
    const os = std.os;

    pub const io_mode = .evented;

    pub fn main() anyerror!void {
    const allocator = std.heap.page_allocator; // TODO use a more appropriate allocator

    var server = net.StreamServer.init(.{});
    defer server.deinit();

    var room = Room{ .clients = std.AutoHashMap(*Client, void).init(allocator) };

    try server.listen(net.Address.parseIp("127.0.0.1", 0) catch unreachable);
    std.debug.warn("listening at {}\n", .{server.listen_address});

    while (true) {
    const client = try allocator.create(Client);
    client.* = Client{
    .conn = try server.accept(),
    .handle_frame = async client.handle(&room),
    };
    try room.clients.putNoClobber(client, {});
    }
    }
    const Client = struct {
    conn: net.StreamServer.Connection,
    handle_frame: @Frame(handle),

    fn handle(self: *Client, room: *Room) !void {
    try self.conn.file.writeAll("server: welcome to teh chat server\n");
    while (true) {
    var buf: [100]u8 = undefined;
    const amt = try self.conn.file.read(&buf);
    const msg = buf[0..amt];
    room.broadcast(msg, self);
    }
    }
    };
    const Room = struct {
    clients: std.AutoHashMap(*Client, void),

    fn broadcast(room: *Room, msg: []const u8, sender: *Client) void {
    var it = room.clients.iterator();
    while (it.next()) |entry| {
    const client = entry.key;
    if (client == sender) continue;
    client.conn.file.writeAll(msg) catch |e| std.debug.warn("unable to send: {}\n", .{e});
    }
    }
    };
    12 changes: 12 additions & 0 deletions instructions.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,12 @@
    Tested with zig 0.5.0+f7f563ea5

    zig build-exe basic-tcp-chat.zig
    ./basic-tcp-chat

    This will print "listening at listening at 127.0.0.1:$PORT"
    To play with it you have to open 2 terminal windows and in each one
    (replacing $PORT with the one printed):

    nc 127.0.0.1 $PORT

    Now the terminals can talk to each other when you type your message and press enter.