我的Go服务器上有一个工作的TCP套接字设置.我接受传入连接,运行for循环并使用net.Conn.Read函数读取传入数据.
但这对我来说没有意义.如何知道已收到完整邮件以便继续返回邮件大小?
这是我目前的代码:
func (tcpSocket *TCPServer) HandleConnection(conn net.Conn) {
println("Handling connection! ", conn.RemoteAddr().String(), " connected!")
recieveBuffer := make([]byte, 50) // largest message we ever get is 50 bytes
defer func() {
fmt.Println("Closing connection for: ", conn.RemoteAddr().String())
conn.Close()
}()
for {
// how does it know the end of a message vs the start of a new one?
messageSize, err := conn.Read(recieveBuffer)
if err != nil {
return
}
if messageSize > 0 { // update keep alive since we got a message
conn.SetReadDeadline(time.Now().Add(time.Second * 5))
}
}
}
Run Code Online (Sandbox Code Playgroud)
让我们说我的应用程序发送一个长度为6个字节的消息(可以是任何大小).如何conn.Read
知道它何时收到所述消息的结束然后继续?
我的经验主要在于C#,所以Go在这里很不寻常.对于我的C#应用程序,消息具有第一个字节中包含的消息大小,然后我使用for循环读取剩余字节直到消息大小.
然而Go中的上述代码似乎得到了完整的消息并继续 - 它是如何自动知道我的消息的大小?
我真的很困惑这是怎么回事,或者当我真正接近它时,它只是运气好.
我的所有消息都在第一个字节中有标题,说明消息的大小.但似乎我在Go服务器上不需要它,我误解了它是如何工作的?
Jim*_*imB 12
TCP不提供任何消息帧,您可以根据您定义的协议缓冲流并解析消息.
解析TCP流时,立即将连接包装在a中通常很有用bufio.Reader
,因为它不仅可以提高读取效率,而且可以为您提供更有用的方法.解析协议的一个示例可能是:
buff := make([]byte, 50)
c := bufio.NewReader(conn)
for {
// read a single byte which contains the message length
size, err := c.ReadByte()
if err != nil {
return err
}
// read the full message, or return an error
_, err := io.ReadFull(c, buff[:int(size)])
if err != nil {
return err
}
fmt.Printf("received %x\n", buff[:int(size)])
}
Run Code Online (Sandbox Code Playgroud)