2014-09-25 9 views
7

Ich suche eine gute Lösung für eine Client/Server-Kommunikation mit UDP-Sockets in Go Sprache.Schreiben an Client UDP Socket in Go

Die Beispiele, die ich im Internet gefunden habe, zeigen mir, wie man Daten an den Server sendet, aber sie lehren nicht, wie man sie zurück zum Client sendet.

Um zu demonstrieren, mein Programm führt Folgendes aus:

Mein Client-Programm erstellt eine Buchse auf der 4444-Port, wie folgt aus:

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

ich einen String und die lokale Adresse an den Server gesendet, So könnte die Zeichenfolge gedruckt und eine OK-Nachricht gesendet werden. Ich verwende gob dafür:

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

Meine Daten Struktur sieht wie folgt aus:

type Data struct{ 
    Msg string 
    Addr string 
} 

Mein Server hört auf den 4444-Port und decodiert das Gob richtig, aber wie kann ich die OK-Nachricht zurück ? Ich bin mit der Client-Adresse, dies zu tun (auf dem Server .GO-Datei):

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

Dann bekomme ich einen Fehlercode:

write udp 127.0.0.1:35290: connection refused 

Wenn der Client versucht, mit dem Server zu verbinden sind Port 4444 erstellt der Client einen Port mit einer Zufallszahl (in diesem Fall 35290), damit sie kommunizieren können. Ich weiß, dass ich die Client-Adresse nicht an den Server weiterleiten sollte, aber conn.RemoteAddress() funktioniert nicht. Eine Lösung, die die Adresse des Kunden entdeckt, würde am meisten geschätzt werden.

Obs .: Ich weiß, dass es ReadFromUDP gibt, damit ich das Paket lesen kann. Soll ich die Adresse des Kunden lesen und die Daten an Gob senden, damit er sie entschlüsseln kann?

+1

Read-Pakete unter Verwendung von [ReadFromUDP] (http://godoc.org/net#UDPConn.ReadFromUDP). Verwenden Sie die von ReadFromUDP zurückgegebene Adresse, um mit [WriteToUDP] (http://godoc.org/net#UDPConn.WriteToUDP) zu antworten. –

+0

Ich habe darüber nachgedacht, aber wie würde Gob in dieser Situation passen? – Aleksandrus

+2

Verschlüsseln Sie den Tropfen mit 'var b bytes.Buffer; err: = gob.NewEncoder (& b) .Encode (v) 'und schreibe b.Bytes() in die Verbindung. Dekodieren Sie die Gobs mit 'err: = gob.NewDecoder (bytes.NewReader (p)) .Decode (& v)' wobei p die Daten sind, die von der Verbindung gelesen werden. –

Antwort

14

Überprüfen Sie die folgenden Beispiele für die Client/Server-Kommunikation über UDP. Die Routine sendResponse dient zum Zurücksenden der Antwort an den Client.

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

Die Zeile conn.Close() in der udpclient.go wird es besser sein, in einen abgelehnten Satz zu setzen, wie: verzögern conn.Close() – alsotoes