GoサーバーにTCPソケット設定があります。私は着信接続を受け入れ、forループを実行し、net.Conn.Read関数を使用して着信データを読み取ります。永続的なTCPソケットに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))
}
}
}
は、私のアプリケーションは、長い6バイト(任意のサイズにすることができます)でメッセージを送るとしましょう。 conn.Read
は、そのメッセージの終わりを受信したときに、そのメッセージの続きをどのように知りますか?
私の経験は主にC#にあるので、ここでは珍しいです。私のC#アプリケーションでは、メッセージは最初のバイトに含まれるメッセージのサイズを持っています。その後、forループを使用して残りのバイトをメッセージサイズまで読み込みます。
しかし、上記のコードは完全なメッセージを受け取っているように見えますが、メッセージのサイズは自動的にどのように知るのですか?
私は実際これがどうやって起こっているのか、それとも私が実際に間違っていると運がうまくいっているのか混乱しています。
私のすべてのメッセージには、メッセージのサイズを示す最初のバイトのヘッダーがあります。しかし、それは私がGoサーバ上でそれを必要としないようだ、私は誤解どのようにこれは動作しますか?
TCPは言語に関係なく同じです。メッセージの境界を正しく処理するかどうかはあなた次第です。 – JimB
だからこそ、すべての例でRead(someBuffer)を使用するのはなぜですか?あなたが境界を伝えることができない場合、いつ読書が使われるでしょうか?私はそれを実際に正しく行う方法の例を見つけることができません。 – WDUK
私はTCP接続から他にどのように読むと思いますか?それがTCPが動作する方法です。ストリームプロトコルであり、単にメッセージの概念はありません。何らかのメッセージエンベロープが必要な場合は、より高いレベルのプロトコルを使用します。 – JimB