net.Conn.Read用于持久TCP套接字的正确方法是什么 [英] Whats the correct way to use net.Conn.Read for persistant TCP sockets

查看:74
本文介绍了net.Conn.Read用于持久TCP套接字的正确方法是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Go服务器上有有效的TCP套接字设置.我接受传入连接,运行for循环并使用net.Conn.Read函数读取传入数据.

I have a working TCP socket setup on my Go server. I accept an incoming connection, run a for loop and read incoming data using the net.Conn.Read function.

但是这对我来说毫无意义.如何知道已收到完整的消息以便继续返回消息大小?

But it just doesn't make sense to me. How does it know the full message has been received in order to continue with a return of message size?

这是我目前的代码:

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

可以说我的应用程序发送的消息长度为6个字节(可以是任意大小). conn.Read 如何知道何时收到所述消息的结尾然后继续?

Lets say my application sends a message which is 6 bytes long (could be any size). How does conn.Read know when its received the end of said message to then continue?

我的经验主要在于C#,所以Go在这里并不常见.对于我的C#应用​​程序,消息具有第一个字节中包含的消息大小,然后使用for循环读取直到消息大小为止的其余字节.

My experience mainly lies in C#, so Go is but unusual here. For my C# application the messages have the size of the message contained in first byte, then i use a for loop to read the remaining bytes up to message size.

但是Go中的上述代码似乎可以获取完整的消息并继续执行-它是如何自动知道我的消息大小的?

Yet the above code in Go seems to get the full message and continues - it some how automatically knows the size of my message?

我真的很困惑这是怎么发生的,或者当我实际上错误地对待它的时候是否运气很好.

I am really confused how this is happening or if its just working by luck when i'm actually approaching it wrong.

我所有的消息的第一个字节都有标头,说明消息的大小.但似乎我在Go服务器上不需要它,我是否误解了它的工作原理?

All my messages have the header in the first byte stating the size of the message. But it seems i don't need it on a Go server, am i misunderstanding how this works?

推荐答案

TCP不提供任何消息框架,由您来缓冲流并根据定义的协议解析消息.

TCP doesn't provide any message framing, it's up to you to buffer the stream and parse the messages according to whatever protocol you've defined.

解析TCP流时,立即将连接包装在 bufio中通常很有用.Reader ,不仅可以提高阅读效率,还可以为您提供更多有用的方法.您可以如何解析协议的示例如下:

When parsing a TCP stream, it's often useful to immediately wrap the connection in a bufio.Reader, as not only can it make reading more efficient, but it provides you with more useful methods. An example of how you could parse your protocol could be:

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

这篇关于net.Conn.Read用于持久TCP套接字的正确方法是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆