监听未使用的 TCP/IP 端口
在此示例中,端口显示在控制台上,程序将监听直到收到请求。将端口设置为 0 时,Ip4Address 会分配一个随机端口。
//! Start an echo TCP server at an unused port.
//!
//! Test with
//! echo "hello zig" | nc localhost <port>
const std = @import("std");
const net = std.net;
const print = std.debug.print;
pub fn main() !void {
const loopback = try net.Ip4Address.parse("127.0.0.1", 0);
const localhost = net.Address{ .in = loopback };
var server = try localhost.listen(.{
.reuse_address = true,
});
defer server.deinit();
const addr = server.listen_address;
print("Listening on {}, access this port to end the program\n", .{addr.getPort()});
const client = try server.accept();
// In real world, you'd want to handle multiple clients, probably in separate threads.
try handleClient(client);
}
fn handleClient(client: net.Server.Connection) !void {
print("Accepted connection from {f}\n", .{client.address});
defer client.stream.close();
var stream_buf: [1024]u8 = undefined;
var reader = client.stream.reader(&stream_buf);
// Here we echo back what we read directly, so the writer buffer is empty
var writer = client.stream.writer(&.{});
while (true) {
print("Waiting for data from {f}...\n", .{client.address});
const msg = reader.interface().takeDelimiterInclusive('\n') catch |err| {
if (err == error.EndOfStream) {
print("{f} closed the connection\n", .{client.address});
return;
} else {
return err;
}
};
print("{f} says {s}", .{ client.address, msg });
try writer.interface.writeAll(msg);
// No need to flush, as writer buffer is empty
}
}
启动后,请尝试像这样进行测试:
echo "hello zig" | nc localhost <port>
默认情况下,程序使用 IPv4 进行监听。如果您想要 IPv6,请使用 ::1 代替 127.0.0.1,将 net.Ip4Address.parse 替换为 net.Ip6Address.parse,并在创建 net.Address 时将字段 .in 替换为 .in6。
(并连接到像 ip6-localhost 之类的地址,具体取决于您的机器设置。)
下一节将演示如何使用 Zig 代码连接到此服务器。