5.5 سرور udp پیشرفته

5.5 سرور udp پیشرفته

در قسمت قبل به ایجاد یک سرور udp ساده و ارسال پکت به آن پرداختیم. در این قسمت با استفاده از یک سرور و کلاینت udp یک پیام رسان بصورت feed میسازیم. عملکرد سرور و کلاینت: یک سرور udp ایجاد میکنیم که تمام کانکشن های موجود را ذخیره میکند و به محض دریافت پیام از هر یک از کانکشن ها پیام را برای تمام کانکشن های دیگر بجر کانکشن ارسال کننده پیام ارسال میکند.

در مرحله اول سروری که کانکشن ها و ارسال پیام را مدیریت میکنید مینویسیم:

 1package main
 2
 3import (
 4    "fmt"
 5    "net"
 6)
 7
 8func main() {
 9    // Set up the server
10    addr := net.UDPAddr{
11        Port: 8000,
12        IP:   net.ParseIP("0.0.0.0"),
13    }
14
15    conn, err := net.ListenUDP("udp", &addr)
16    if err != nil {
17        fmt.Println("Error listening:", err)
18        return
19    }
20
21    defer conn.Close()
22    fmt.Println("Server started on port", addr.Port)
23
24    // Listen for incoming messages
25    buffer := make([]byte, 1024)
26
27    clients := make(map[string]*net.UDPAddr)
28	
29    for {
30        n, clientAddr, err := conn.ReadFromUDP(buffer)
31        if err != nil {
32            fmt.Println("Error reading:", err)
33            continue
34        }
35
36        // Add new client
37        if _, ok := clients[clientAddr.String()]; !ok {
38            clients[clientAddr.String()] = clientAddr
39            fmt.Println("New client joined:", clientAddr.String())
40        }
41
42        // Broadcast message to all clients
43        message := buffer[:n]
44        for _, addr := range clients {
45            if addr.String() != clientAddr.String() {
46                _, err = conn.WriteToUDP(message, addr)
47                if err != nil {
48                    fmt.Println("Error broadcasting message:", err)
49                }
50            }
51        }
52    }
53}

در این قسمت یک سرور udp ایجاد کرده ایم و هر کانکشن جدید را به لیست کانکشن های خود اضافه میکنیم. همچنین در ازای هر پیام دریافتی از سمت کانکشن ها آن را برای کانکشن های دیگر ارسال میکنیم.

در ادامه یک کلاینت ساده برای سرور خود مینویسیم که پیام هارا نمایش دهد و متن ورودی در ترمینال را به سرور ارسال کند.

 1package main
 2
 3import (
 4    "bufio"
 5    "fmt"
 6    "net"
 7    "os"
 8)
 9
10func main() {
11    // Set up connection to the server
12    conn, err := net.Dial("udp", "localhost:8000")
13    if err != nil {
14        fmt.Println("Error connecting:", err)
15        return
16    }
17    defer conn.Close()
18
19   
20    go func() {
21        for {
22            buf := make([]byte, 1024) // buffer for incoming message
23            n, err := conn.Read(buf)
24            if err != nil {
25                fmt.Println("Error receiving message:", err)
26                continue
27            }
28            fmt.Printf("Received message: %s\n", string(buf[:n]))
29        }
30    }()
31    
32    // Read input from terminal and send to server
33    scanner := bufio.NewScanner(os.Stdin)
34    for {
35		    // send messages to server
36        fmt.Print("Enter message: ")
37        if !scanner.Scan() {
38            break
39        }
40        message := scanner.Text()
41        _, err = conn.Write([]byte(message))
42        if err != nil {
43            fmt.Println("Error sending message:", err)
44            continue
45        }
46    }
47}

در این کد ما تمام پیام های دریافتی از سرور را چاپ میکنیم و هر پیامی که کاربر در ترمینال وارد کند را به سرور ارسال میکنیم.

بعد از اتمام کار برای تست کد خود سه ترمینال مجزا بار میکنیم. و در یکی از سرور ها فایل server.go و در دو ترمینال دیگر فایل client.go را اجرا میکنیم.

هر پیامی که توسط هر کلاینتی ارسال شود برای دیگر کلاینت ها قابل مشاهده است.

توجه کنید اسم فایل ها بر اساس اسم انتخابی شما است. همچنین توجه داشته باشید که شما میتوانید هر تعداد دلخواهی کلاینت را اجرا کنید.