در قسمت قبل به ایجاد یک سرور 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
را اجرا میکنیم.
هر پیامی که توسط هر کلاینتی ارسال شود برای دیگر کلاینت ها قابل مشاهده است.
توجه کنید اسم فایل ها بر اساس اسم انتخابی شما است. همچنین توجه داشته باشید که شما میتوانید هر تعداد دلخواهی کلاینت را اجرا کنید.