Golang: delimitador de dados do cliente / servidor TCP
Não tenho certeza de como formular a pergunta e se ela realmente se relaciona apenas à linguagem go, mas o que estou tentando fazer é ter um servidor e cliente tcp que troquem dados no meio, basicamente o cliente transmitirá grandes quantidades de dados em menores pedaços para o servidor, o servidor aguardará para ler todos os fragmentos de dados e responderá com um código de status que será lido pelo cliente e, com base nisso, fará outro trabalho.
Eu uso a função abaixo comoteste para ler os dados do cliente e do servidor (observe, eu sei que isso não é perfeito, mas está apenas testando):
func createBufferFromConn(conn net.Conn) *bytes.Buffer {
buffer := &bytes.Buffer{}
doBreak := false
for {
incoming := make([]byte, BUFFER_SIZE)
conn.SetReadDeadline(time.Now().Add(time.Second * 2))
bytesRead, err := conn.Read(incoming)
conn.SetReadDeadline(time.Time{})
if err != nil {
if err == io.EOF {
fmt.Println(err)
} else if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
fmt.Println(err)
}
doBreak = true
}
if doBreak == false && bytesRead == 0 {
continue
}
if bytesRead > 0 {
buffer.Write(incoming[:bytesRead])
if bytes.HasSuffix(buffer.Bytes(), []byte("|")) {
bb := bytes.Trim(buffer.Bytes(), "|")
buffer.Reset()
buffer.Write(bb)
doBreak = true
}
}
if doBreak {
break
}
}
return buffer
}
Agora, no meu caso, se eu conectar via telnet (o código go também inclui umclient()
para conectar aoserver()
) e digito algo comotest 12345|
É justo que tudo funcione perfeitamente e o buffer contém todos os bytes gravados no telnet (exceto o canal que é removido pela chamada Trim ()).
Se eu remover oif bytes.HasSuffix(buffer.Bytes(), []byte("|")) {
Se você bloquear o código, obterá um tempo limite após 2 segundos, novamente, conforme o esperado, porque nenhum dado é recebido nessa quantidade de tempo e o servidor fecha a conexão. Se eu não definir um prazo de leitura para a conexão, ele esperará uma eternidade para ler os dados e nunca saberá quando parar.
Acho que minha pergunta é: se eu enviar vários blocos de dados, preciso especificar um delimitador para que eu saiba quando parar de ler a conexão e evite esperar para sempre ou o tempo limite da conexão do servidor?