Go の net/http パッケージを使用したネットワーク プログラミングの領域では、基になるソケットに直接アクセスする必要がある場合があります。ネットワーク接続(net.Conn)。
開発者は net/http を使用してファイルを提供しようとしていますが、問題が発生しました: ハンドラー関数 (net.Conn) で http.ResponseWriter の基礎となるソケットにアクセスする必要があります。プラットフォーム固有のシステムコールを実行します。
Go 1.13 以降では、次の手順に従って net.Conn をリクエスト コンテキストに保存できます:
このリリースより前には、次の 2 つの代替手段がありました。
リモート アドレス文字列を使用する
TCP ポートでリッスンする場合 サーバーの場合、 net.Conn.RemoteAddr().String() は接続ごとに一意であり、グローバル接続マップへのキーとして使用できます。
net.Listener.Accept() をオーバーライド
UNIX ソケットでリッスンしているサーバーの場合、net.Listener.Accept() をオーバーライドして、ファイル記述子を使用して返すことができます。よりユニークな価値観。
Go 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 中国語 Web サイトの他の関連記事を参照してください。