Zig unix socket read and write

Hello this is my first post here, although I have been following this community for a long time. I have written an unix scoket client server in zig 0.15.2 and trying to migrate to zig 0.16.0. Here is an example code

const std = @import("std");
const Io = std.Io;
const net = std.Io.net;

pub fn main(init: std.process.Init) !void {
    //const arena: std.mem.Allocator = init.arena.allocator();
    const io = init.io;

    var stdout_buffer: [1024]u8 = undefined;
    var stdout_file_writer: Io.File.Writer = .init(.stdout(), io, &stdout_buffer);
    const stdout = &stdout_file_writer.interface;

    const unix_sf: []const u8 = "/tmp/zig_unix.socket";

    try stdout.print("Connecting to unix socket to: {s}\n", .{unix_sf});
    try stdout.flush(); 

    const socket = try std.Io.net.UnixAddress.init(unix_sf);
    const stream = try socket.connect(io);
    defer stream.close(io);

    var write_buffer: [1500]u8 = undefined;
    var writer = stream.writer(io, write_buffer[0..]);

    _ = try writer.interface.writeAll("Hello check\n");
    _ = try writer.interface.flush();

    var read_buffer: [1500]u8 = undefined;
    var reader = stream.reader(io,read_buffer[0..]);

    while(true) {
        const msg = try reader.interface.takeArray(read_buffer.len);
        try stdout.print("Received Message: {s}\n", .{msg});
        try io.sleep(.fromMilliseconds(10), .boot);
    }
}

This builds and runs when i open a unix socket in another Terminal and start the application

$ ./zig-out/bin/zig_examples 
Connecting to unix socket to: /tmp/zig_unix.socket

$ nc -lU /tmp/zig_unix.socket
Hello check

but when is try to send a message back to the application

$ nc -lU /tmp/zig_unix.socket
Hello check
Check Hello

I dont recieve any message back

$ ./zig-out/bin/zig_examples 
Connecting to unix socket to: /tmp/zig_unix.socket


Could some one explain why? Thanks in Advance

1 Like

I think the issue here is that you’re using reader.interface.takeArray(read_buffer.len). If I understand correctly, this function blocks until it can fill the entire length of the read buffer - 1500 bytes in this case. The message you send with nc is only a few bytes, so the program is still waiting for much more data before it reaches the write to stdout in the loop.
You also need to flush stdout after each write in the loop.

Try using something like Io.Reader.takeDelimiter or similar to read from the socket.

3 Likes

Hello thank you for the reply, I have tried using takeDelimiter('\n'), this also does not work for some reason

    while(true) {
        const msg = try reader.interface.takeDelimiter('\n');
        try stdout.print("Received Message: {s}\n", .{msg.?});
        try io.sleep(.fromMilliseconds(10), .boot);
    }

The outputs are the same

$ nc -lU /tmp/zig_unix.socket
Hello check
Check Hello
Chekc Hello


$ ./zig-out/bin/zig_examples 
Connecting to unix socket to: /tmp/zig_unix.socket



You do get the data, but you are not flushing stdout so it never gets to the console.

1 Like

The flush for stdout is missing. The data is currently sitting in a buffer. To actually get it to print:

    while (true) {
        const msg = try reader.interface.takeDelimiter('\n');
        try stdout.print("Received Message: {s}\n", .{msg orelse break});
        try stdout.flush();
    }

The sleep is also not necessary, as the reader/writer interface is blocking, i.e. takeDelimiter will just wait until data arrives.

And welcome to ziggit! (-:

2 Likes

Oh yes, this seems to work. Thanks you.

1 Like