|
// socket_diagnostic.wren - Diagnose socket issues
|
|
import "socket" for Socket, SocketInstance
|
|
|
|
foreign class Host {
|
|
foreign static signalDone()
|
|
}
|
|
|
|
var mainFiber = Fiber.new {
|
|
System.print("=== Socket Diagnostic Test ===\n")
|
|
|
|
// Test 1: Basic socket creation
|
|
System.print("Test 1: Socket creation")
|
|
var sock1 = SocketInstance.new()
|
|
if (sock1 && !sock1[0]) {
|
|
System.print(" ✓ Socket created successfully")
|
|
sock1[1].close()
|
|
} else {
|
|
System.print(" ✗ Failed: %(sock1 ? sock1[0] : "null result")")
|
|
}
|
|
|
|
// Test 2: Bind to different ports
|
|
System.print("\nTest 2: Port binding")
|
|
var ports = [18000, 18001, 18002, 18003, 18004]
|
|
var boundSockets = []
|
|
|
|
for (port in ports) {
|
|
var result = SocketInstance.new()
|
|
if (result && !result[0]) {
|
|
var sock = result[1]
|
|
var bindResult = sock.bind("127.0.0.1", port)
|
|
if (bindResult && !bindResult[0]) {
|
|
System.print(" ✓ Bound to port %(port)")
|
|
boundSockets.add(sock)
|
|
} else {
|
|
System.print(" ✗ Failed to bind port %(port): %(bindResult ? bindResult[0] : "null")")
|
|
sock.close()
|
|
}
|
|
}
|
|
}
|
|
|
|
// Clean up
|
|
for (sock in boundSockets) {
|
|
sock.close()
|
|
}
|
|
|
|
// Test 3: Listen without bind (should fail)
|
|
System.print("\nTest 3: Listen without bind")
|
|
var result = SocketInstance.new()
|
|
if (result && !result[0]) {
|
|
var sock = result[1]
|
|
var listenResult = sock.listen(5)
|
|
if (listenResult && listenResult[0]) {
|
|
System.print(" ✓ Correctly failed: %(listenResult[0])")
|
|
} else {
|
|
System.print(" ✗ Unexpectedly succeeded")
|
|
}
|
|
sock.close()
|
|
}
|
|
|
|
// Test 4: Full server setup
|
|
System.print("\nTest 4: Full server setup")
|
|
result = SocketInstance.new()
|
|
if (!result || result[0]) {
|
|
System.print(" ✗ Failed to create server socket")
|
|
} else {
|
|
var serverSock = result[1]
|
|
System.print(" ✓ Server socket created")
|
|
|
|
var bindResult = serverSock.bind("0.0.0.0", 18080)
|
|
if (!bindResult || bindResult[0]) {
|
|
System.print(" ✗ Bind failed: %(bindResult ? bindResult[0] : "null")")
|
|
serverSock.close()
|
|
} else {
|
|
System.print(" ✓ Bound to 0.0.0.0:18080")
|
|
|
|
var listenResult = serverSock.listen(10)
|
|
if (!listenResult || listenResult[0]) {
|
|
System.print(" ✗ Listen failed: %(listenResult ? listenResult[0] : "null")")
|
|
} else {
|
|
System.print(" ✓ Listening with backlog 10")
|
|
}
|
|
serverSock.close()
|
|
}
|
|
}
|
|
|
|
// Test 5: Rapid open/close
|
|
System.print("\nTest 5: Rapid socket open/close")
|
|
var successCount = 0
|
|
for (i in 1..100) {
|
|
var r = SocketInstance.new()
|
|
if (r && !r[0]) {
|
|
successCount = successCount + 1
|
|
r[1].close()
|
|
}
|
|
}
|
|
System.print(" Created and closed %(successCount)/100 sockets")
|
|
|
|
// Test 6: Connect to non-existent server (should fail quickly)
|
|
System.print("\nTest 6: Connect to non-existent server")
|
|
var startTime = System.clock
|
|
var connectResult = SocketInstance.connect("127.0.0.1", 19999)
|
|
var elapsed = System.clock - startTime
|
|
if (connectResult && connectResult[0]) {
|
|
System.print(" ✓ Correctly failed in %(elapsed)s: %(connectResult[0])")
|
|
} else {
|
|
System.print(" ✗ Unexpectedly succeeded")
|
|
if (connectResult && connectResult[1]) {
|
|
connectResult[1].close()
|
|
}
|
|
}
|
|
|
|
// Test 7: Actual echo test with verbose output
|
|
System.print("\nTest 7: Simple echo test")
|
|
|
|
// Create server
|
|
var serverResult = SocketInstance.new()
|
|
if (!serverResult || serverResult[0]) {
|
|
System.print(" ✗ Server socket creation failed: %(serverResult ? serverResult[0] : "null")")
|
|
} else {
|
|
var serverSock = serverResult[1]
|
|
System.print(" ✓ Server socket created")
|
|
|
|
// Try multiple ports in case one is in use
|
|
var serverPort = 0
|
|
var bindSuccess = false
|
|
for (port in [20000, 20001, 20002, 20003, 20004]) {
|
|
var bindResult = serverSock.bind("127.0.0.1", port)
|
|
if (bindResult && !bindResult[0]) {
|
|
serverPort = port
|
|
bindSuccess = true
|
|
System.print(" ✓ Server bound to port %(port)")
|
|
break
|
|
}
|
|
}
|
|
|
|
if (!bindSuccess) {
|
|
System.print(" ✗ Could not bind to any port")
|
|
serverSock.close()
|
|
} else {
|
|
var listenResult = serverSock.listen(5)
|
|
if (!listenResult || listenResult[0]) {
|
|
System.print(" ✗ Listen failed: %(listenResult ? listenResult[0] : "null")")
|
|
serverSock.close()
|
|
} else {
|
|
System.print(" ✓ Server listening")
|
|
|
|
// Server fiber
|
|
var serverDone = false
|
|
var serverFiber = Fiber.new {
|
|
System.print(" [Server] Waiting for connection...")
|
|
var attempts = 0
|
|
while (attempts < 500) {
|
|
var acceptResult = serverSock.accept()
|
|
if (acceptResult && !acceptResult[0] && acceptResult[1]) {
|
|
System.print(" [Server] ✓ Accepted connection")
|
|
var clientSock = SocketInstance.fromFd(acceptResult[1])
|
|
|
|
// Read from client
|
|
var readAttempts = 0
|
|
while (readAttempts < 100) {
|
|
var readResult = clientSock.read(256)
|
|
if (readResult && !readResult[0] && readResult[1] && readResult[1].count > 0) {
|
|
System.print(" [Server] ✓ Received: %(readResult[1])")
|
|
|
|
// Echo back
|
|
var writeErr = clientSock.write(readResult[1])
|
|
if (writeErr) {
|
|
System.print(" [Server] ✗ Write failed: %(writeErr)")
|
|
} else {
|
|
System.print(" [Server] ✓ Echoed back")
|
|
}
|
|
break
|
|
}
|
|
readAttempts = readAttempts + 1
|
|
Fiber.yield()
|
|
}
|
|
|
|
clientSock.close()
|
|
break
|
|
}
|
|
attempts = attempts + 1
|
|
Fiber.yield()
|
|
}
|
|
if (attempts >= 500) {
|
|
System.print(" [Server] ✗ No connection after %(attempts) attempts")
|
|
}
|
|
serverDone = true
|
|
}
|
|
|
|
// Client fiber
|
|
var clientDone = false
|
|
var clientFiber = Fiber.new {
|
|
// Wait a bit for server to be ready
|
|
for (i in 1..10) Fiber.yield()
|
|
|
|
System.print(" [Client] Connecting to port %(serverPort)...")
|
|
var connectResult = SocketInstance.connect("127.0.0.1", serverPort)
|
|
if (!connectResult || connectResult[0]) {
|
|
System.print(" [Client] ✗ Connect failed: %(connectResult ? connectResult[0] : "null")")
|
|
} else {
|
|
var clientSock = connectResult[1]
|
|
System.print(" [Client] ✓ Connected")
|
|
|
|
var message = "Hello, Server!"
|
|
var writeErr = clientSock.write(message)
|
|
if (writeErr) {
|
|
System.print(" [Client] ✗ Write failed: %(writeErr)")
|
|
} else {
|
|
System.print(" [Client] ✓ Sent: %(message)")
|
|
|
|
// Read echo
|
|
var readAttempts = 0
|
|
while (readAttempts < 100) {
|
|
var readResult = clientSock.read(256)
|
|
if (readResult && !readResult[0] && readResult[1] && readResult[1].count > 0) {
|
|
System.print(" [Client] ✓ Received echo: %(readResult[1])")
|
|
break
|
|
}
|
|
readAttempts = readAttempts + 1
|
|
Fiber.yield()
|
|
}
|
|
}
|
|
|
|
clientSock.close()
|
|
}
|
|
clientDone = true
|
|
}
|
|
|
|
// Run both fibers
|
|
serverFiber.call()
|
|
clientFiber.call()
|
|
|
|
var iterations = 0
|
|
while ((!serverDone || !clientDone) && iterations < 1000) {
|
|
if (!serverDone) serverFiber.call()
|
|
if (!clientDone) clientFiber.call()
|
|
iterations = iterations + 1
|
|
Fiber.yield()
|
|
}
|
|
|
|
System.print(" Test completed after %(iterations) iterations")
|
|
serverSock.close()
|
|
}
|
|
}
|
|
}
|
|
|
|
System.print("\n=== Diagnostic Complete ===")
|
|
Host.signalDone()
|
|
|
|
while(true) { Fiber.yield() }
|
|
}
|