【发布时间】:2021-06-18 21:08:15
【问题描述】:
我正在尝试在 golang 中创建一个 tcp 服务器/客户端连接。我正在发送消息长度,因此服务器将接受多条消息,直到达到消息长度。当我尝试读取消息头以确定消息长度时,没有输出。当调用“conn.read(b)”时,代码似乎卡在了服务器的 tcpreader 函数的 for 循环中。什么可能导致此失败?
我的服务器代码:
package main
import (
"bufio"
"bytes"
"encoding/binary"
"fmt"
"log"
"net"
"strings"
)
type hdr struct {
magicNum uint64
msgLen uint32
msgType uint16
padding uint16
}
func tcpReader(conn net.Conn) {
foundLength := false
var hdr struct {
magicNum uint64
msgLen uint32
msgType uint16
padding uint16
}
hdrSize := 16
fmt.Println("tcpReader() header size %v", hdrSize)
//localBuffer := new(bytes.Buffer)
defer conn.Close()
for {
if !foundLength {
fmt.Println("tcpReader() Getting the lenght of the message")
var b = make([]byte, hdrSize)
// where the code seems to get stuck
read, err := conn.Read(b)
if err != nil {
fmt.Println("Failed to read header size %v", hdrSize)
fmt.Println(err)
continue
}
fmt.Println("tcpReader() read header bytes %v %v x", read, string(b))
if read != hdrSize { //add logic check magic number etc
fmt.Println("invalid header")
continue
}
err = binary.Read(bytes.NewReader(b[:16]), binary.BigEndian, &hdr)
if err != nil {
log.Fatal(err)
}
fmt.Println("tcpReader() read header bytes %v", hdr.msgLen)
foundLength = true
// messageLength = int(binary.BigEndian.Uint64(b))
} else {
var message = make([]byte, hdr.msgLen)
read, err := conn.Read(message)
if err != nil {
fmt.Println(err)
continue
}
fmt.Println("Received bytes: %v", read)
if read != int(hdr.msgLen) {
//Add logic to append the read message and update the readSofarBytes etc
fmt.Println("invalid data")
continue
}
fmt.Println("Received:", string(message))
foundLength = false
}
}
}
func main() {
fmt.Println("Launching server...")
fmt.Println("Listen on port")
/* addr, err := net.ResolveTCPAddr("ip4", "127.0.0.1:8081")
if err != nil {
panic(err)
}*/
ln, err := net.Listen("tcp", "127.0.0.1:8081")
if err != nil {
log.Fatal(err)
}
defer ln.Close()
fmt.Println("Accept connection on port")
for {
conn, err := ln.Accept()
if err != nil {
log.Fatal(err)
}
fmt.Println("Calling handleConnection")
//go handleConnection(conn)
go tcpReader(conn)
}
}
我的客户代码:
package main
import (
"bufio"
"bytes"
"encoding/binary"
"fmt"
"net"
)
type hdr struct {
magicNum uint64
msgLen int
msgType uint16
padding uint16
msg string
}
func main() {
var bin_buf bytes.Buffer
msg := hdr{magicNum: 123456789,
msgLen: 60,
msgType: 2,
padding: 0,
msg: "Hello world this is tcp message with big header"}
msg.msgLen = int(len(msg.msg))
fmt.Printf("message length %v\n", msg.msgLen)
binary.Write(&bin_buf, binary.BigEndian, msg)
addr, _ := net.ResolveTCPAddr("tcp", ":8081")
conn, err := net.DialTCP("tcp", nil, addr)
if err != nil {
panic(err.Error())
}
// conn.Write(bin_buf.Bytes())
conn.Write(bin_buf.Bytes())
//conn.Write([]byte("Hello from Clinet\n"))
message, _ := bufio.NewReader(conn).ReadString('\n')
fmt.Print(message)
conn.Close()
}
【问题讨论】:
标签: go tcp network-programming