2014-10-04 2 views
2

나는 서버 net.Conn을 가지고 있으며, 클라이언트가 사용하려고하는 일반 텍스트 프로토콜 또는 SSL/TLS인지 확인하기 위해 바이트를 읽기 전에이를 들여다보고 싶습니다.가서 읽지 않고 Conn으로 엿보기

http://golang.org/pkg/net/을 확인하면 Conn 인터페이스에 이와 같은 내용이없는 것으로 보입니다. 나는 iobuf.Reader을 사용할 수는 있지만 클라이언트가 SSL/TLS를 사용하는 것으로 밝혀지면 tls.Conn(conn, config)을 통해 TLS Conn을 받고 싶습니다. iobuf.Reader은 원래 Conn에서 읽을 것이므로 tls.Conn의 핸드 셰이크가 실패합니다.

그럼 Go에서 Conn을 들여다 볼 수있는 방법이 있나요? (C/C++ 소켓에서 MSG_PEEK과 같은 것)? 또는 Conn에서 처음 몇 바이트를 읽은 후에 tls.Conn을 만들 수 있습니까?

답변

8

당신은 솔루션에 매우 가깝습니다. 당신이 잘못 본 유일한 것은 Conn에서 먼저 읽는 것입니다. 당신은 맞습니다 bufio.ReaderPeek 방법은 갈 방법입니다. 트릭은 버퍼링 된 판독기를 먼저 만들고 Conn에서 읽는 대신 버퍼 판독기에서 Peek으로 전화하는 것입니다. 여기에 당신이 필요로 할 것입니다 bufferedConn 유형입니다 :

type bufferedConn struct { 
    r  *bufio.Reader 
    net.Conn // So that most methods are embedded 
} 

func newBufferedConn(c net.Conn) bufferedConn { 
    return bufferedConn{bufio.NewReader(c), c} 
} 

func newBufferedConnSize(c net.Conn, n int) bufferedConn { 
    return bufferedConn{bufio.NewReaderSize(c, n), c} 
} 

func (b bufferedConn) Peek(n int) ([]byte, error) { 
    return b.r.Peek(n) 
} 

func (b bufferedConn) Read(p []byte) (int, error) { 
    return b.r.Read(p) 
} 

무엇이하는 일은 당신이 net.Conn을 포함시켜 정상적인 net.Conn 모든 방법을 (에 액세스 할 수 있습니다 - 당신은 또한 래퍼 함수를 ​​작성할 수는 있지만,이 많이 있습니다 쉽고 청소기), 그리고 추가로 bufferedReaderPeekRead 방법에 대한 액세스를 제공합니다 (그것은 Read가해야 Read에, 버퍼의 net.ConnPeek 때문에 데이터를 저장에 직접적는 bufferedReader에 너무 후속 호출을 호출하는 것이 중요합니다 최초로이 버퍼로부터 임의의 데이터를 읽어내는 일이 가능합니다. e의 기초가되는 것 net.Conn).

newBufferedConnSize 기능은 현재 기본 버퍼 크기는 4096 바이트 있지만, 기술적 것을 아마 불필요한 주어집니다 당신은 주어진 크기로 Peek를 호출하지 특히 ​​(이 오류를 반환 ErrBufferFull을 할 수있는에 의존하는 거라면), 당신은 명시 적으로 적어도 당신이 엿볼 예정인 바이트 수만큼 큰 크기로 설정해야합니다.

Go Playground에서 확인하십시오.

+0

굉장, 제안대로 작동합니다, 감사합니다! – ldx

관련 문제