>백엔드 개발 >Golang >Go에서 net/http 응답의 기본 소켓에 어떻게 액세스할 수 있나요?

Go에서 net/http 응답의 기본 소켓에 어떻게 액세스할 수 있나요?

DDD
DDD원래의
2024-11-07 10:36:03385검색

How Can I Access the Underlying Socket of a net/http Response in Go?

net/http 응답의 기본 소켓 검색

Go의 net/http 패키지를 사용한 네트워크 프로그래밍 영역에서 때로는 기본 소켓에 직접 액세스해야 할 수도 있습니다. 네트워크 연결(net.Conn).

문제 설명

개발자가 net/http를 사용하여 파일을 제공하려고 하는데 문제에 직면합니다. 핸들러 함수(net.Conn)에서 http.ResponseWriter의 기본 소켓에 액세스해야 합니다. 플랫폼별 시스템 호출을 수행합니다.

해결 방법

Go 1.13 이상에서는 다음 단계에 따라 net.Conn을 요청 컨텍스트에 저장할 수 있습니다.

  • SaveConnInContext 함수를 사용하여 net을 저장합니다. .Conn은 요청 컨텍스트에 저장됩니다.
  • GetConn 함수를 사용하여 요청에서 net.Conn을 검색합니다.

이번 릴리스 이전에는 두 가지 대안이 있었습니다.

원격 주소 문자열 사용

TCP 포트에서 수신 대기용 서버용 , net.Conn.RemoteAddr().String()은 각 연결마다 고유하며 전역 연결 맵의 키로 사용될 수 있습니다.

net.Listener.Accept() 재정의

UNIX 소켓을 수신하는 서버의 경우 net.Listener.Accept()를 재정의하여 파일 설명자를 사용하여 반환할 수 있습니다. 좀 더 독특한 가치.

코드 예시

가기 1.13 이상

<code class="go">// SaveConnInContext stores the net.Conn in the request context.
func SaveConnInContext(ctx context.Context, c net.Conn) context.Context {
  return context.WithValue(ctx, ConnContextKey, c)
}

// GetConn retrieves the net.Conn from the request context.
func GetConn(r *http.Request) net.Conn {
  return r.Context().Value(ConnContextKey).(net.Conn)
}</code>

TCP 연결용

<code class="go">// ConnStateEvent handles connection state events.
func ConnStateEvent(conn net.Conn, event http.ConnState) {
  if event == http.StateActive {
    conns[conn.RemoteAddr().String()] = conn
  } else if event == http.StateHijacked || event == http.StateClosed {
    delete(conns, conn.RemoteAddr().String())
  }
}

// GetConn retrieves the net.Conn from a map using the remote address as a key.
func GetConn(r *http.Request) net.Conn {
  return conns[r.RemoteAddr]
}</code>

UNIX 연결용

<code class="go">// NewUnixListener creates a new UNIX listener with a modified Accept() method.
func NewUnixListener(path string) (net.Listener, error) {
  // ... (setup code)

  l, err := net.Listen("unix", path)
  if err != nil {
    return nil, err
  }

  return NewConnSaveListener(l), nil
}

// NewConnSaveListener wraps a listener and overrides the Accept() method.
func NewConnSaveListener(wrap net.Listener) net.Listener {
  return connSaveListener{wrap}
}

// remoteAddrPtrConn overrides the RemoteAddr() method to return a unique value.
type remoteAddrPtrConn struct {
  net.Conn
  ptrStr string
}

func (self remoteAddrPtrConn) RemoteAddr() net.Addr {
  return remoteAddrPtr{self.ptrStr}
}

// remoteAddrPtr implements the net.Addr interface.
type remoteAddrPtr struct {
  ptrStr string
}

func (remoteAddrPtr) Network() string {
  return ""
}

func (self remoteAddrPtr) String() string {
  return self.ptrStr
}

// Accept overrides the default Accept() method to store the net.Conn in a map.
func (self connSaveListener) Accept() (net.Conn, error) {
  conn, err := self.Listener.Accept()
  ptrStr := fmt.Sprintf("%d", &conn)
  conns[ptrStr] = conn
  return remoteAddrPtrConn{conn, ptrStr}, err
}</code>

이러한 방법을 통해 개발자는 http.ResponseWriter의 기본 소켓에 쉽게 액세스하여 사용자 정의 네트워크 처리에 대한 다양한 가능성을 열 수 있습니다.

위 내용은 Go에서 net/http 응답의 기본 소켓에 어떻게 액세스할 수 있나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.