2017-12-01 3 views
2

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의 위 코드는 전체 메시지를 얻은 것처럼 보이며 계속됩니다.이 메시지는 내 메시지의 크기를 자동으로 어떻게 알 수 있습니까?

나는 이것이 실제로 어떻게 일어나고 있는지, 아니면 내가 실제로 잘못 접근하고있을 때 운이 좋았는지 혼란 스럽다.

내 모든 메시지에는 메시지의 크기를 나타내는 첫 번째 바이트의 헤더가 있습니다. 하지만 Go 서버에서는이 기능이 필요하지 않은 것 같습니다. 어떻게 작동하는지 오해하니?

+0

TCP는 언어에 관계없이 동일하게 작동합니다. 메시지 경계를 올바르게 처리하는 것은 당신에게 달려 있습니다. – JimB

+0

그렇다면 모든 예제는 그런 것들을 처리하지 못하기 때문에 왜 Read (someBuffer)를 사용합니까? 경계를 말할 수 없다면 읽기는 언제 사용됩니까? 실제로 올바르게 수행하는 방법에 대한 예제를 찾을 수 없습니다. – WDUK

+0

TCP 연결에서 읽는 방법을 모르겠다. 이것이 TCP가 작동하는 방식이며, 스트림 프로토콜이며 단순히 메시지 개념이 없습니다. 어떤 종류의 메시지 봉투가 필요하면 더 높은 수준의 프로토콜을 사용하십시오. – JimB

답변

3

TCP는 메시지 프레임을 제공하지 않습니다. TCP는 스트림을 버퍼링하고 정의한 프로토콜에 따라 메시지를 구문 분석합니다.

TCP 스트림을 구문 분석 할 때 연결을 즉시 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)]) 
} 
+0

아, 그게 내가 찾고 있던 것 같아! 고맙습니다 :) – WDUK

관련 문제