Maison > développement back-end > Golang > le corps du texte

Comment puis-je accéder au socket sous-jacent d'une réponse net/http dans Go ?

DDD
Libérer: 2024-11-07 10:36:03
original
296 Les gens l'ont consulté

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

Récupération du socket sous-jacent d'une réponse net/http

Dans le domaine de la programmation réseau avec le package net/http de Go, nous pouvons parfois avoir besoin d'accéder directement au sous-jacent connexion réseau (net.Conn).

Énoncé du problème

Un développeur essaie de servir des fichiers en utilisant net/http, mais rencontre un problème : avoir besoin d'accéder au socket sous-jacent de http.ResponseWriter dans la fonction de gestionnaire ( net.Conn) pour effectuer des appels système spécifiques à la plate-forme.

Solution de contournement

Dans Go 1.13 et supérieur, net.Conn peut être stocké dans le contexte de la requête en suivant ces étapes :

  • Utilisez la fonction SaveConnInContext pour enregistrer net. .Conn est enregistré dans le contexte de la demande.
  • Récupérez net.Conn de la requête à l'aide de la fonction GetConn.

Avant cette version, il existait deux alternatives :

Utiliser la chaîne d'adresse distante

Pour écouter sur un port TCP Pour les serveurs , net.Conn.RemoteAddr().String() est unique pour chaque connexion et peut être utilisée comme clé de la carte de connexion globale.

Remplacer net.Listener.Accept()

Pour les serveurs écoutant sur des sockets UNIX, nous pouvons remplacer net.Listener.Accept() pour utiliser le descripteur de fichier pour renvoyer une valeur plus unique.

Exemple de code

Go 1.13 et supérieur

<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>
Copier après la connexion

Pour la connexion 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>
Copier après la connexion

Pour les connexions 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>
Copier après la connexion

Grâce à ces méthodes, les développeurs peuvent facilement accéder au socket sous-jacent de http.ResponseWriter, leur ouvrant ainsi une gamme de possibilités de gestion réseau personnalisée.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!