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.Thread.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", .{}); }