无法在Go编程中通过TCP发送gob数据。

huangapple go评论92阅读模式
英文:

Unable to send gob data over TCP in Go Programming

问题

我有一个客户端服务器应用程序,使用TCP连接

客户端:

type Q struct {
    sum int64
}

type P struct {
    M, N int64
}

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

服务器:

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)
}

服务器上的结果是{0, 0},因为我不知道如何从net.Conn获取bytes.Buffer变量。

是否有任何方法可以通过TCP发送gob变量?

如果是真的,如何做到这一点?或者在通过TCP发送数字方面有任何替代方法?

非常感谢任何帮助或示例代码。

英文:

I have a client server application, using TCP connection

Client:

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)
}

Server:

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)
}

The result on serve is {0, 0} because I don't know how to obtain a bytes.Buffer variable from net.Conn.

Is there any way for sending gob variables over TCP ?

If true, how can this be done ? Or there are any alternative in sending numbers over TCP ?

Any help or sample code would really be appreciated.

答案1

得分: 43

这是一个完整的示例。

服务器:

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 {
        // 处理错误
    }
    for {
        conn, err := ln.Accept() // 这会阻塞,直到连接或错误
        if err != nil {
            // 处理错误
            continue
        }
        go handleConnection(conn) // 一个 goroutine 处理连接,以便循环可以接受其他连接
    }
}

客户端:

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");
}

启动服务器,然后启动客户端,你会看到服务器显示接收到的 P 值。

一些观察结果以使其清晰:

  • 当你在一个套接字上监听时,你应该将打开的套接字传递给一个处理它的 goroutine。
  • Conn 实现了 ReaderWriter 接口,这使得使用它很容易:你可以将它传递给 DecoderEncoder
  • 在一个真实的应用程序中,你可能会在一个被两个程序导入的包中定义 P 结构。
英文:

Here's a complete example.

Server:

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
    }
}

Client :

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");
}

Launch the server, then the client, and you see the server displaying the received P value.

A few observations to make it clear :

  • When you listen on a socket, you should pass the open socket to a goroutine that will handle it.
  • Conn implements the Reader and Writer interfaces, which makes it easy to use : you can give it to a Decoder or Encoder
  • In a real application you would probably have the P struct definition in a package imported by both programs

huangapple
  • 本文由 发表于 2012年6月26日 14:49:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/11202058.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定