2014-09-25 9 views
7

Szukam dobrego rozwiązania dla komunikacji klient/serwer z gniazdami UDP w języku Go.Napisz do klienta UDP Gniazdo w Go

Przykłady znalezione w Internecie pokazują, jak przesłać dane do serwera, ale nie uczą, jak je odesłać do klienta.

Aby wykazać, mój program wykonuje następujące operacje:

Mój program klient tworzy gniazdo na porcie w 4444, podobnie jak to:

con, err := net.Dial("udp", "127.0.0.1:4444") 

wysłałem ciąg i lokalny adres do serwera, aby mógł wydrukować ciąg znaków i wysłać komunikat OK. Używam gębę za to:

enc := gob.NewEncoder(con) 
enc.Encode(Data{"test", con.LocalAddr().String()}) 

Moje dane struktura wygląda następująco:

type Data struct{ 
    Msg string 
    Addr string 
} 

Serwer nasłuchuje na porcie w 4444 i dekoduje Gob poprawnie, ale jak mogę wysłać OK wiadomość z powrotem ? Używam adres klienta, aby to zrobić (na serwerze .GO pliku):

con, err := net.Dial("udp", data.Addr) 

Następnie pojawia się kod błędu:

write udp 127.0.0.1:35290: connection refused 

Gdy klient próbuje połączyć się z serwera port 4444, klient tworzy port z liczbą losową (w tym przypadku 35290), aby mogli się komunikować. Wiem, że nie powinienem przekazywać adresu klienta na serwer, ale conn.RemoteAddress() nie działa. Rozwiązanie, które odkryje adres klienta, będzie najbardziej docenione.

Obs .: Wiem, że jest ReadFromUDP, więc mogę przeczytać paczkę. Czy powinienem je przeczytać, odkryć adres klienta i przesłać dane do Goba, aby mógł je odszyfrować?

+1

pakiety odczytywano przy użyciu [ReadFromUDP] (http://godoc.org/net#UDPConn.ReadFromUDP). Użyj adresu zwróconego przez ReadFromUDP, aby odpowiedzieć używając [WriteToUDP] (http://godoc.org/net#UDPConn.WriteToUDP). –

+0

Myślałem o tym, ale jak Gob pasowałby do tej sytuacji? – Aleksandrus

+2

Zakoduj gob do bufora używając 'var b bytes.Buffer; err: = gob.NewEncoder (& b) .Encode (v) 'i napisz b.Bytes() do połączenia. Odkodować kolce za pomocą 'err: = gob.NewDecoder (bytes.NewReader (p)). Decode (& v)' gdzie p to dane odczytane z połączenia. –

Odpowiedz

14

Sprawdź poniższe próbki dla komunikacji klient/serwer przez UDP. Procedura sendResponse służy do wysyłania odpowiedzi do klienta.

udpclient.go

package main 
import (
    "fmt" 
    "net" 
    "bufio" 
) 

func main() { 
    p := make([]byte, 2048) 
    conn, err := net.Dial("udp", "127.0.0.1:1234") 
    if err != nil { 
     fmt.Printf("Some error %v", err) 
     return 
    } 
    fmt.Fprintf(conn, "Hi UDP Server, How are you doing?") 
    _, err = bufio.NewReader(conn).Read(p) 
    if err == nil { 
     fmt.Printf("%s\n", p) 
    } else { 
     fmt.Printf("Some error %v\n", err) 
    } 
    conn.Close() 
} 

udpserver.go

package main 
import (
    "fmt" 
    "net" 
) 


func sendResponse(conn *net.UDPConn, addr *net.UDPAddr) { 
    _,err := conn.WriteToUDP([]byte("From server: Hello I got your mesage "), addr) 
    if err != nil { 
     fmt.Printf("Couldn't send response %v", err) 
    } 
} 


func main() { 
    p := make([]byte, 2048) 
    addr := net.UDPAddr{ 
     Port: 1234, 
     IP: net.ParseIP("127.0.0.1"), 
    } 
    ser, err := net.ListenUDP("udp", &addr) 
    if err != nil { 
     fmt.Printf("Some error %v\n", err) 
     return 
    } 
    for { 
     _,remoteaddr,err := ser.ReadFromUDP(p) 
     fmt.Printf("Read a message from %v %s \n", remoteaddr, p) 
     if err != nil { 
      fmt.Printf("Some error %v", err) 
      continue 
     } 
     go sendResponse(ser, remoteaddr) 
    } 
} 
+0

Linia conn.Close() w udpclient.go będzie lepiej umieścić w odroczonym zdaniu, np .: odrzuć conn.Close() – alsotoes