영구 TCP 소켓을 위한 net.Conn.Read의 올바른 사용
Go에서 영구 TCP 소켓 작업에는 연결을 설정하고 지속적으로 들어오는 데이터를 읽는 중입니다. net.Conn.Read 함수는 소켓에서 데이터를 검색하는 역할을 담당하지만 해당 동작이 즉시 명확하지 않을 수 있습니다.
TCP의 메시지 프레이밍 이해
일부와는 달리 다른 프로토콜에서는 TCP가 본질적으로 메시지 프레이밍을 제공하지 않습니다. 즉, 연속 데이터 스트림 내에서 메시지를 분리하는 방법을 정의하는 것은 애플리케이션에 달려 있습니다.
헤더를 사용한 기존 메시지 프레이밍
이전 C# 경험에서 메시지 앞에는 메시지 크기가 포함된 헤더가 추가되었습니다. 이 접근 방식을 사용하면 수신 애플리케이션이 후속 메시지의 정확한 길이를 알 수 있습니다.
Go가 메시지 처리를 처리하는 방법
Go는 다른 접근 방식을 취합니다. 기본적으로 net.Conn.Read()에는 메시지 끝을 결정하는 고유 메커니즘이 없습니다. 귀하의 질문에 제공한 코드 조각은 메시지 경계를 고려하지 않고 루프에서 conn.Read()를 호출합니다. 이는 특정 시나리오에서 작동할 수 있지만 안정적이거나 확장 가능한 솔루션은 아닙니다.
해결책: 사용자 정의 메시지 프레이밍
영구 TCP 소켓을 올바르게 처리하려면 다음을 구현해야 합니다. 사용자 정의 메시지 프레임. 여기에는 들어오는 데이터를 버퍼링하고 자신이 정의한 프로토콜에 따라 파싱하는 작업이 포함됩니다.
bufio.Reader 사용 예
권장되는 접근 방식 중 하나는 내장된 bufio를 사용하는 것입니다. .Net을 포장하는 리더.Conn. 이 래퍼는 추가 기능을 제공하고 데이터를 더 효율적으로 읽을 수 있도록 해줍니다.
import ( "bufio" "fmt" "io" "net" ) func main() { listener, err := net.Listen("tcp", ":8080") if err != nil { panic(err) } for { conn, err := listener.Accept() if err != nil { continue } go handleConnection(conn) } } func handleConnection(conn net.Conn) { defer conn.Close() r := bufio.NewReader(conn) for { size, err := r.ReadByte() if err != nil { return } buff := make([]byte, size) if _, err := io.ReadFull(r, buff); err != nil { return } fmt.Println("Received:", buff) } }
이 예에서 handlerConnection 함수는 먼저 연결에서 단일 바이트를 읽어 후속 메시지의 길이를 나타냅니다. 그런 다음 버퍼를 생성하고 io.ReadFull을 사용하여 지정된 크기의 전체 메시지를 읽습니다. 이를 통해 애플리케이션은 다양한 길이의 메시지를 원활하게 처리할 수 있습니다.
위 내용은 영구 TCP 소켓을 위해 Go에서 net.Conn.Read를 사용하여 메시지 프레이밍을 안정적으로 처리하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!