2012-06-26 10 views
18

Mam aplikacji klient-serwer, używając połączenia TCPNie można wysyłać dane porcji przez TCP w Go Programowanie

Klient:

type Q struct { 
    sum int64 
} 

type P struct { 
    M, N int64 
} 

func main() { 
    ... 
    //read M and N 
    ... 
    tcpAddr, err := net.ResolveTCPAddr("tcp4", service) 
    ... 
    var p P 
    p.M = M 
    p.N = N 
    err = enc.Encode(p) 
} 

Serwer:

type Q struct { 
    sum int64 
} 

type P struct { 
    M, N int64 
} 

func main() { 
    ... 
    tcpAddr, err := net.ResolveTCPAddr("ip4", service) 
    listener, err := net.ListenTCP("tcp", tcpAddr) 
    ... 
    var connB bytes.Buffer 
    dec := gob.NewDecoder(&connB) 
    var p P 
    err = dec.Decode(p) 
    fmt.Printf("{%d, %d}\n", p.M, p.N) 
} 

Wynik na służyć ma {0, 0}, ponieważ nie wiem, jak uzyskać zmienną bytes.Buffer z net.Conn.

Czy istnieje sposób przesyłania zmiennych GOB przez TCP?

Jeśli to prawda, w jaki sposób można to zrobić? Czy jest jakaś alternatywa w wysyłaniu liczb przez TCP?

Każda pomoc lub kod przykładowy byłby naprawdę doceniany.

Odpowiedz

41

Oto pełny przykład.

Serwer:

package main 

import (
    "fmt" 
    "net" 
    "encoding/gob" 
) 

type P struct { 
    M, N int64 
} 
func handleConnection(conn net.Conn) { 
    dec := gob.NewDecoder(conn) 
    p := &P{} 
    dec.Decode(p) 
    fmt.Printf("Received : %+v", p); 
    conn.Close() 
} 

func main() { 
    fmt.Println("start"); 
    ln, err := net.Listen("tcp", ":8080") 
    if err != nil { 
     // handle error 
    } 
    for { 
     conn, err := ln.Accept() // this blocks until connection or error 
     if err != nil { 
      // handle error 
      continue 
     } 
     go handleConnection(conn) // a goroutine handles conn so that the loop can accept other connections 
    } 
} 

Klient:

package main 

import (
    "fmt" 
    "log" 
    "net" 
    "encoding/gob" 
) 

type P struct { 
    M, N int64 
} 

func main() { 
    fmt.Println("start client"); 
    conn, err := net.Dial("tcp", "localhost:8080") 
    if err != nil { 
     log.Fatal("Connection error", err) 
    } 
    encoder := gob.NewEncoder(conn) 
    p := &P{1, 2} 
    encoder.Encode(p) 
    conn.Close() 
    fmt.Println("done"); 
} 

Uruchom serwer, klient, i widzisz serwer wyświetlania odebranej wartości P.

kilka uwag, aby było jasne:

  • Kiedy słuchasz na gnieździe, należy przesunąć otwartą gniazdo do goroutine że będzie go obsługiwać.
  • Conn implementuje interfejsy Reader i Writer, dzięki czemu jest łatwy w użyciu: można dać go do Decoder lub Encoder
  • W rzeczywistej aplikacji byłoby prawdopodobnie masz definicję P struct w opakowaniu importowanego przez obu programów
+0

Twój przykład działa świetnie. Dzięki. Mam tylko pytanie, w jaki sposób mogę wysłać wynik z serwera do klienta? – Emanuel

+9

Gniazdo jest dwukierunkowe. Wystarczy napisać na nim w funkcji 'handleConnection', dokładnie tak, jak piszesz w kliencie. –

+0

Działa to świetnie. Dzięki za przykład. Chcę wysłać ciąg {map [string]} do serwera. Ale nie zostanie zdekodowany na końcu serwera. Wszelkie sugestie na ten temat? – Dany

Powiązane problemy