Backlog/lib/enet/src/test_client.zig

150 lines
5.2 KiB
Zig

const std = @import("std");
const enet = @import("enet");
const SERVER_HOST = "127.0.0.1";
const SERVER_PORT = 7777;
const CHANNEL_COUNT = 2;
const CONNECT_TIMEOUT = 5000; // 5 seconds
pub fn main() !void {
std.debug.print("Starting ENet test client, connecting to {s}:{}\n", .{ SERVER_HOST, SERVER_PORT });
// Initialize ENet
try enet.initialize();
defer enet.deinitialize();
// Create client host
const host = enet.c.enet_host_create(null, 1, CHANNEL_COUNT, 0, 0);
if (host == null) {
std.debug.print("Failed to create ENet client host\n", .{});
return error.HostCreationFailed;
}
defer enet.c.enet_host_destroy(host);
// Set up server address
var address = enet.c.ENetAddress{
.host = 0,
.port = SERVER_PORT,
};
// Resolve server hostname
if (enet.c.enet_address_set_host(&address, SERVER_HOST) != 0) {
std.debug.print("Failed to resolve server address: {s}\n", .{SERVER_HOST});
return error.AddressResolutionFailed;
}
// Connect to server
const peer = enet.c.enet_host_connect(host, &address, CHANNEL_COUNT, 0);
if (peer == null) {
std.debug.print("Failed to create connection to server\n", .{});
return error.ConnectionFailed;
}
var event: enet.c.ENetEvent = undefined;
var connected = false;
// Wait for connection to complete
std.debug.print("Connecting to server...\n", .{});
if (enet.c.enet_host_service(host, &event, CONNECT_TIMEOUT) > 0 and event.type == enet.c.ENET_EVENT_TYPE_CONNECT) {
std.debug.print("Connected to server successfully!\n", .{});
connected = true;
} else {
std.debug.print("Failed to connect to server within timeout\n", .{});
enet.c.enet_peer_reset(peer);
return error.ConnectionTimeout;
}
if (connected) {
// Send test messages
const test_messages = [_][]const u8{
"Hello from test client!",
"This is message 2",
"Testing ENet loopback",
"Final message",
"quit", // This will trigger server shutdown
};
for (test_messages, 0..) |message, i| {
std.debug.print("Sending message {}: '{s}'\n", .{ i + 1, message });
// Create and send packet
const packet = enet.c.enet_packet_create(message.ptr, message.len, enet.c.ENET_PACKET_FLAG_RELIABLE);
_ = enet.c.enet_peer_send(peer, 0, packet);
// Flush the send queue
enet.c.enet_host_flush(host);
// Wait for response
var response_received = false;
var attempts: u32 = 0;
const max_attempts = 10;
while (!response_received and attempts < max_attempts) {
const result = enet.c.enet_host_service(host, &event, 500); // 500ms timeout per attempt
attempts += 1;
if (result > 0) {
switch (event.type) {
enet.c.ENET_EVENT_TYPE_RECEIVE => {
const data = @as([*]u8, @ptrCast(event.packet.*.data))[0..event.packet.*.dataLength];
std.debug.print("Received response: '{s}'\n", .{data});
enet.c.enet_packet_destroy(event.packet);
response_received = true;
},
enet.c.ENET_EVENT_TYPE_DISCONNECT => {
std.debug.print("Server disconnected\n", .{});
connected = false;
break;
},
else => {},
}
} else if (result < 0) {
std.debug.print("Error servicing host\n", .{});
break;
}
}
if (!response_received and connected) {
std.debug.print("No response received for message {}\n", .{i + 1});
}
if (!connected) break;
// Small delay between messages
std.time.sleep(100 * std.time.ns_per_ms);
}
// Disconnect if still connected
if (connected) {
std.debug.print("Disconnecting from server...\n", .{});
enet.c.enet_peer_disconnect(peer, 0);
// Wait for disconnection to complete
var disconnected = false;
var disconnect_attempts: u32 = 0;
const max_disconnect_attempts = 10;
while (!disconnected and disconnect_attempts < max_disconnect_attempts) {
const result = enet.c.enet_host_service(host, &event, 500);
disconnect_attempts += 1;
if (result > 0 and event.type == enet.c.ENET_EVENT_TYPE_DISCONNECT) {
std.debug.print("Disconnected successfully\n", .{});
disconnected = true;
} else if (result < 0) {
break;
}
}
if (!disconnected) {
std.debug.print("Force disconnecting...\n", .{});
enet.c.enet_peer_reset(peer);
}
}
}
std.debug.print("Client shutting down\n", .{});
}