Refactor ExampleDatagramSession to improve error handling and simplify datagram sending/receiving logic; enhance output messages for better clarity.

This commit is contained in:
eyedeekay
2025-10-06 12:46:01 -04:00
parent 984021c5cf
commit 2eebe2eb2f

View File

@@ -88,111 +88,74 @@ func Test_DatagramServerClient(t *testing.T) {
func ExampleDatagramSession() {
// Creates a new DatagramSession, which behaves just like a net.PacketConn.
// Note: This example requires a running I2P router with SAM bridge enabled.
// If no I2P router is available, the example will print an error and return.
// This example demonstrates I2P datagram communication by sending messages
// and attempting to receive them through the I2P network.
//
// Requirements: This example requires a running I2P router with SAM bridge enabled.
const samBridge = "127.0.0.1:7656"
sam, err := NewSAM(samBridge)
if err != nil {
fmt.Println("Error creating SAM connection (I2P router may not be running):", err.Error())
fmt.Printf("Failed to connect to I2P SAM bridge at %s: %v\n", samBridge, err)
return
}
defer sam.Close()
keys, err := sam.NewKeys()
if err != nil {
fmt.Println("Error generating keys:", err.Error())
sam.Close()
fmt.Printf("Failed to generate I2P keys: %v\n", err)
return
}
myself := keys.Addr()
// See the example Option_* variables.
// Create datagram session with small tunnel configuration for faster setup
dg, err := sam.NewDatagramSession("DGTUN", keys, Options_Small, 0)
if err != nil {
fmt.Println("Error creating datagram session:", err.Error())
sam.Close()
fmt.Printf("Failed to create datagram session: %v\n", err)
return
}
defer dg.Close()
// Try to lookup a destination (this may fail if I2P is not fully started)
someone, err := sam.Lookup("zzz.i2p")
if err != nil {
fmt.Println("Warning: Could not resolve zzz.i2p (I2P may still be starting up):", err.Error())
// Use a placeholder address for demonstration
someone = myself
}
// Send datagrams (these operations may timeout if I2P tunnels are not ready)
// For this example, we'll send messages to ourselves to demonstrate functionality
fmt.Println("Sending datagrams...")
// Use timeouts for I2P operations
sendTimeout := make(chan bool, 1)
go func() {
defer func() {
if r := recover(); r != nil {
fmt.Printf("Error during send operation: %v\n", r)
}
sendTimeout <- true
}()
_, err1 := dg.WriteTo([]byte("Hello stranger!"), someone)
if err1 != nil {
fmt.Println("Warning: Could not send to destination:", err1.Error())
}
_, err2 := dg.WriteTo([]byte("Hello myself!"), myself)
if err2 != nil {
fmt.Println("Warning: Could not send to self:", err2.Error())
}
}()
// Wait for send operations with timeout
select {
case <-sendTimeout:
// Sends completed (successfully or with errors)
case <-time.After(30 * time.Second):
fmt.Println("Warning: Send operations timed out (I2P tunnels may not be ready)")
// Send a message to ourselves (this should work if I2P tunnels are established)
_, err = dg.WriteTo([]byte("Hello myself!"), myself)
if err != nil {
dg.Close()
sam.Close()
fmt.Printf("Failed to send datagram: %v\n", err)
return
}
// Try to receive a datagram with reasonable timeout
fmt.Println("Attempting to receive datagram...")
receiveTimeout := make(chan bool, 1)
var received bool
go func() {
defer func() {
if r := recover(); r != nil {
fmt.Printf("Error during receive operation: %v\n", r)
}
receiveTimeout <- true
}()
// Set a reasonable deadline for the receive operation (I2P operations need time)
dg.SetReadDeadline(time.Now().Add(60 * time.Second))
buf := make([]byte, 31*1024)
n, _, err := dg.ReadFrom(buf)
if err != nil {
fmt.Println("Could not receive datagram:", err.Error())
} else {
fmt.Printf("Got message: %s\n", string(buf[:n]))
received = true
}
}()
// Wait for receive operation with timeout
select {
case <-receiveTimeout:
if !received {
fmt.Println("No datagram received (this is normal if I2P tunnels are not fully established)")
}
case <-time.After(30 * time.Second):
fmt.Println("Receive operation timed out (normal behavior when no messages are available)")
buf := make([]byte, 31*1024)
n, addr, err := dg.ReadFrom(buf)
if err != nil {
dg.Close()
sam.Close()
fmt.Printf("Failed to receive datagram within 60 seconds: %v\n", err)
return
}
fmt.Printf("Received message: %s\n", string(buf[:n]))
fmt.Printf("From address: %s\n", addr.String())
// Clean up resources
dg.Close()
sam.Close()
fmt.Println("DatagramSession example completed")
return
// Output:
// Sending datagrams...
// Attempting to receive datagram...
// Received message: Hello myself!
// From address: [I2P address]
// DatagramSession example completed
}