Berkeley Sockets – Wikipedia wiki

before-content-x4

API de communication inter-processus

after-content-x4

Sockets de Berkeley est une interface de programmation d’applications (API) pour les prises Internet et les prises de domaine UNIX, utilisées pour la communication inter-processus (IPC). Il est généralement mis en œuvre en tant que bibliothèque de modules liens. Il est originaire du système d’exploitation de 4,2BSD UNIX, qui a été publié en 1983.

Une prise est une représentation abstraite (poignée) pour le point de terminaison local d’un chemin de communication réseau. L’API Berkeley Sockets le représente comme un descripteur de fichier (poignée de fichier) dans la philosophie UNIX qui fournit une interface commune pour l’entrée et la sortie aux flux de données.

Les prises de Berkeley ont évolué avec peu de modification d’un En fait Standard dans un composant de la spécification POSIX. Le terme POSIX SOCKETS est essentiellement synonyme de Sockets de Berkeley , mais ils sont également connus comme Sockets BSD , reconnaissant la première implémentation dans la distribution du logiciel Berkeley.

Historique et implémentations [ modifier ]]

Berkeley Sockets est originaire du système d’exploitation 4.2BSD UNIX, publié en 1983, en tant qu’interface de programmation. Ce n’est qu’en 1989, cependant, la publication de la bibliothèque de réseaux de l’Université de Californie pourrait publier des versions de système d’exploitation et de réseautage des contraintes de licence de l’Unix propriétaire d’AT&T Corporation.

Tous les systèmes d’exploitation modernes implémentent une version de l’interface Berkeley Socket. Il est devenu l’interface standard pour les applications exécutées sur Internet. Même l’implémentation Winsock pour MS Windows, créée par des développeurs non affiliés, suit étroitement la norme.

after-content-x4

L’API BSD Sockets est écrite dans le langage de programmation C. La plupart des autres langages de programmation fournissent des interfaces similaires, généralement écrites comme une bibliothèque de wrapper basée sur l’API C. [d’abord]

Sockets BSD et POSIX [ modifier ]]

Au fur et à mesure que l’API Berkeley Socket a évolué et a finalement donné l’API Posix Socket, [2] Certaines fonctions ont été obsolètes ou supprimées et remplacées par d’autres. L’API POSIX est également conçue pour être réentrente et prend en charge IPv6.

Action BSD Posix
Conversion de l’adresse texte à l’adresse emballée INET_ATON INET_PTON
Conversion de l’adresse emballée à l’adresse texte INET_NTOA INET_NTOP
Recherche vers l’avant pour le nom / service de l’hôte Gethostbyname, GethostbyAddr, getServbyname, getServbyport getaddrinfo
Recherche inversée pour le nom / service de l’hôte gethostbyaddr, getervbyport getNameinfo

Alternatives [ modifier ]]

L’API d’interface de couche de transport basée sur les cours d’eau (TLI) offre une alternative à l’API de socket. De nombreux systèmes qui fournissent l’API TLI fournissent également l’API Berkeley Socket.

Les systèmes non UNIX exposent souvent l’API Berkeley Socket avec une couche de traduction à une API de mise en réseau native. Plan 9 [3] et Genode [4] Utilisez des API de système de fichiers avec des fichiers de contrôle plutôt que des descripteurs de fichiers.

L’interface de socket Berkeley est définie dans plusieurs fichiers d’en-tête. Les noms et le contenu de ces fichiers diffèrent légèrement entre les implémentations. En général, ils incluent:

Déposer Description
sys / socket.h Fonctions de prise de base et structures de données.
netinet / in.h AF_INET et AF_INET6 Adresse les familles et leurs familles de protocole correspondantes, PF_INET et PF_INET6. Il s’agit notamment des adresses IP standard et des numéros de port TCP et UDP.
sys / un.h PF_UNIX et PF_LOCAL ADRESS FAMILLE. Utilisé pour la communication locale entre les programmes exécutés sur le même ordinateur.
Arpa / inet.h Fonctions pour manipuler les adresses IP numériques.
netdb.h Fonctions pour traduire les noms de protocole et les noms d’hôtes en adresses numériques. Recherche les données locales ainsi que les services de noms.

Fonctions API de socket [ modifier ]]

Diagramme de flux de la transaction client-serveur à l’aide de sockets avec le protocole de contrôle de transmission (TCP).

L’API Berkeley Socket fournit généralement les fonctions suivantes:

  • prise() Crée une nouvelle prise d’un certain type, identifié par un numéro entier, et y attribue des ressources système.
  • lier() est généralement utilisé du côté du serveur et associe une prise à une structure d’adresse de socket, c’est-à-dire une adresse IP locale spécifiée et un numéro de port.
  • écouter() est utilisé du côté du serveur et provoque une prise TCP liée à entrer dans l’état d’écoute.
  • connecter() est utilisé côté client et attribue un numéro de port local gratuit à une prise. Dans le cas d’une prise TCP, elle provoque une tentative d’établir une nouvelle connexion TCP.
  • accepter() est utilisé du côté du serveur. Il accepte une tentative entrante reçue de créer une nouvelle connexion TCP à partir du client distant et crée un nouveau socket associé à la paire d’adresses de socket de cette connexion.
  • envoyer() , recv () , Sento () , et recvfrom () sont utilisés pour envoyer et recevoir des données. Les fonctions standard écrire() et lire() peut également être utilisé.
  • fermer() provoque la libération des ressources du système allouées à une prise. En cas de TCP, la connexion est terminée.
  • gethostbyname () et GethostbyAddr () sont utilisés pour résoudre les noms et adresses d’hôtes. IPv4 uniquement.
  • getAddrinfo () et freeaddrinfo () sont utilisés pour résoudre les noms et adresses d’hôtes. IPv4, IPv6.
  • sélectionner() est utilisé pour suspendre, en attendant qu’une ou plusieurs d’une liste fournie de sockets soient prêtes à lire, prêtes à écrire ou qui ont des erreurs.
  • sondage() est utilisé pour vérifier l’état d’une prise dans un ensemble de prises. L’ensemble peut être testé pour voir si une prise peut être écrite, lire à partir ou si une erreur s’est produite.
  • getockopt () est utilisé pour récupérer la valeur actuelle d’une option de socket particulière pour la prise spécifiée.
  • setsockopt () est utilisé pour définir une option de prise particulière pour la prise spécifiée.

prise [ modifier ]]

La fonction prise() Crée un point de terminaison pour la communication et renvoie un descripteur de fichier pour la prise. Il utilise trois arguments:

  • domaine , qui spécifie la famille du protocole de la prise créée. Par exemple:
    • De_INET pour le protocole réseau IPv4 (IPv4 uniquement)
    • Af_inet6 pour IPv6 (et dans certains cas, compatible en arrière avec IPv4)
    • Af_unix pour la prise locale (à l’aide d’un nœud de système de fichiers spécial)
  • taper , un des:
    • Sock_stream (Service de flux fiable ou sockets de flux)
    • Sock_dgram (Service Datagram ou Sockets Datagram)
    • Sock_seqpacket (Service de paquets séquencés fiable)
    • Sock_raw (protocoles bruts au sommet de la couche réseau)
  • protocole Spécification du protocole de transport réel à utiliser. Les plus courants sont Protot_tcp , Protot_sctp , Proto_udp , Protot_dccp . Ces protocoles sont spécifiés dans le fichier netinet / in.h . La valeur 0 Peut être utilisé pour sélectionner un protocole par défaut dans le domaine et le type sélectionnés.

La fonction renvoie -d’abord Si une erreur s’est produite. Sinon, il renvoie un entier représentant le descripteur nouvellement affecté.

lier [ modifier ]]

lier() associe une prise à une adresse. Lorsqu’une prise est créée avec prise() , il ne reçoit qu’une famille de protocole, mais n’a pas été attribué d’adresse. Cette association doit être effectuée avant que le socket puisse accepter les connexions des autres hôtes. La fonction a trois arguments:

  • sockfd , un descripteur représentant la prise
  • my_addr , un pointeur vers un sockddr structure représentant l’adresse à lier.
  • ajouter à , un champ de type socklen_t spécifiant la taille du sockddr structure.

lier() Renvoie 0 sur le succès et -1 si une erreur se produit.

écouter [ modifier ]]

Une fois qu’une prise a été associée à une adresse, écouter() Le prépare pour les connexions entrantes. Cependant, cela n’est nécessaire que pour les modes de données orientés vers le flux (orienté connexion), c’est-à-dire pour les types de socket ( Sock_stream , Sock_seqpacket ). écouter() nécessite deux arguments:

  • sockfd , un descripteur de socket valide.
  • arriéré , un entier représentant le nombre de connexions en attente qui peuvent être mis en file d’attente à tout moment. Le système d’exploitation place généralement un plafond sur cette valeur.

Une fois qu’une connexion est acceptée, elle est désactivée. Au succès, 0 est retourné. Si une erreur se produit, -1 est renvoyé.

accepter [ modifier ]]

Lorsqu’une application écoute des connexions axées sur le flux provenant d’autres hôtes, il est informé de ces événements (cf. SELECT () fonction) et doit initialiser la connexion à l’aide de la fonction accepter() . Il crée une nouvelle prise pour chaque connexion et supprime la connexion de la file d’attente d’écoute. La fonction a les arguments suivants:

  • sockfd , Le descripteur de la prise d’écoute qui a la file d’attente de connexion.
  • intelligent , un pointeur vers une structure Sockaddr pour recevoir les informations d’adresse du client.
  • ajouter à , un pointeur vers un socklen_t Emplacement qui spécifie la taille de la structure d’adresse du client transmise pour accepter (). Quand accepter() Renvoie, cet emplacement contient la taille (en octets) de la structure.

accepter() Renvoie le nouveau descripteur de socket pour la connexion acceptée ou la valeur -d’abord Si une erreur se produit. Toute communication supplémentaire avec l’hôte distant se produit désormais via cette nouvelle prise.

Les prises de données ne nécessitent pas de traitement par accepter () car le récepteur peut immédiatement répondre à la demande à l’aide de la prise d’écoute.

connecter [ modifier ]]

connecter() Établit un lien de communication direct à un hôte distant spécifique identifié par son adresse via une prise, identifiée par son descripteur de fichier.

Lorsque vous utilisez un protocole axé sur la connexion, cela établit une connexion. Certains types de protocoles sont sans connexion, notamment le protocole de datagramme utilisateur. Lorsqu’il est utilisé avec des protocoles sans connexion, connecter définit l’adresse distante pour l’envoi et la réception de données, permettant l’utilisation de fonctions telles que envoyer et recv . Dans ces cas, la fonction de connexion empêche la réception des datagrammes d’autres sources.

connecter() Renvoie un entier représentant le code d’erreur: 0 représente le succès, tandis que -d’abord représente une erreur. Historiquement, dans les systèmes dérivés de BSD, l’état d’un descripteur de socket n’est pas défini si l’appel à connecter Échec (comme il est spécifié dans la spécification UNIX unique), donc, les applications portables doivent fermer immédiatement le descripteur de socket et obtenir un nouveau descripteur avec socket (), dans le cas où l’appel à connecter () échoue.

Gethostbyname et Gethostbyaddr [ modifier ]]

Les fonctions gethostbyname () et GethostbyAddr () sont utilisés pour résoudre les noms et adresses d’hôtes dans le système de noms de domaine ou les autres mécanismes de résolveur de l’hôte local (par exemple, / etc / la recherche d’hôtes). Ils renvoient un pointeur à un objet de type HOSTENT STRUCT , qui décrit un hôte de protocole Internet. Les fonctions utilisent les arguments suivants:

  • nom Spécifie le nom DNS de l’hôte.
  • addr Spécifie un pointeur vers un struct in_addr contenant l’adresse de l’hôte.
  • seul spécifie la longueur, en octets, de addr .
  • taper Spécifie le type de famille d’adresse (par exemple, AF_INET) de l’adresse hôte.

Les fonctions renvoient un pointeur nul en cas d’erreur, auquel cas l’entier externe h_errno Peut être vérifié pour voir s’il s’agit d’une défaillance temporaire ou d’un hôte non valide ou inconnu. Sinon un valide structure hôte * est retourné.

Ces fonctions ne sont pas strictement un composant de l’API de socket BSD, mais sont souvent utilisées conjointement avec les fonctions de l’API. De plus, ces fonctions sont désormais considérées comme des interfaces héritées pour interroger le système de noms de domaine. De nouvelles fonctions qui sont entièrement autorisées au protocole (support IPv6) ont été définies. Ces nouvelles fonctions sont getAddrinfo () et getNameInfo (), et sont basées sur un nouveau addrinfo Structure de données.

Protocole et adresser les familles [ modifier ]]

L’API Berkeley Socket est une interface générale pour la mise en réseau et la communication interproçue, et prend en charge l’utilisation de divers protocoles de réseau et architectures d’adresse.

Ce qui suit répertorie un échantillon de familles de protocoles (précédés de l’identifiant symbolique standard) défini dans une implémentation Linux ou BSD moderne:

Une prise pour les communications est créée avec le prise() fonction, en spécifiant la famille du protocole souhaité ( Pf_ -Identificateur) comme argument.

Le concept de conception original de l’interface de socket se distinguait entre les types de protocole (familles) et les types d’adresses spécifiques que chacun peut utiliser. Il a été envisagé qu’une famille de protocole puisse avoir plusieurs types d’adresses. Les types d’adresses ont été définis par des constantes symboliques supplémentaires, en utilisant le préfixe DE au lieu de PF . Le DE -Les identificateurs sont destinés à toutes les structures de données qui traitent spécifiquement du type d’adresse et non de la famille du protocole.
Cependant, ce concept de séparation du protocole et du type d’adresse n’a pas trouvé de support de mise en œuvre et le DE -Les sociétés ont été définies par l’identifiant de protocole correspondant, laissant la distinction entre DE et PF constantes comme argument technique sans conséquence pratique. En effet, une grande confusion existe dans l’utilisation appropriée des deux formes. [6]

La spécification POSIX.1—2008 ne spécifie aucun PF -Constants, mais seulement DE -Constants [7]

Prises brutes [ modifier ]]

Les prises brutes fournissent une interface simple qui contourne le traitement par la pile TCP / IP de l’hôte. Ils permettent la mise en œuvre de protocoles de réseautage dans l’espace utilisateur et aident à déboguer de la pile de protocoles. [8] Les prises brutes sont utilisées par certains services, tels que ICMP, qui fonctionnent sur la couche Internet du modèle TCP / IP.

Mode de blocage et non bloquant [ modifier ]]

Les prises de Berkeley peuvent fonctionner dans l’un des deux modes: blocage ou non bloquant.

Une prise de blocage ne renvoie pas le contrôle avant d’avoir envoyé (ou reçu) certaines ou toutes les données spécifiées pour l’opération. Il est normal qu’une prise de blocage de ne pas envoyer toutes les données. La demande doit vérifier la valeur de retour pour déterminer le nombre d’octets envoyés ou reçus et il doit renvoyer les données non déjà traitées. [9] Lorsque vous utilisez des prises de blocage, une considération particulière doit être accordée à accepter () car elle peut toujours bloquer après avoir indiqué la lisibilité si un client se déconnecte pendant la phase de connexion.

Un socket non bloquant renvoie tout ce qui se trouve dans le tampon de réception et se poursuit immédiatement. S’il n’est pas écrit correctement, les programmes utilisant des prises non bloquantes sont particulièrement sensibles aux conditions de course en raison des variances de la vitesse de liaison du réseau. [ citation requise ]]

Une prise est généralement définie sur le mode de blocage ou de non-blocage à l’aide des fonctions FCNTL et IOCTL.

Terminer les prises [ modifier ]]

Le système d’exploitation ne libère pas les ressources allouées à une prise jusqu’à ce que la prise est fermée. Ceci est particulièrement important si le connecter L’appel échoue et sera récité.

Lorsqu’une application ferme une prise, seule l’interface vers la prise est détruite. Il est de la responsabilité du noyau de détruire la prise en interne. Parfois, une prise peut entrer TEMPS D’ATTENTE État, du côté du serveur, jusqu’à 4 minutes. [dix]

Sur les systèmes SVR4 Utilisation de fermer() peut éliminer les données. L’utilisation de fermer() ou So_linger peut être nécessaire sur ces systèmes pour garantir la livraison de toutes les données. [11]

Exemple client-serveur à l’aide de TCP [ modifier ]]

Le protocole de contrôle de transmission (TCP) est un protocole axé sur la connexion qui fournit une variété de fonctionnalités de correction d’erreur et de performances pour la transmission des flux d’octets. Un processus crée une prise TCP en appelant le prise() fonction avec les paramètres de la famille du protocole ( PF INET , Pf_inet6 ), le mode socket pour les sockets de flux ( Sock_stream ), et l’identifiant du protocole IP pour TCP ( Protot_tcp ).

Serveur [ modifier ]]

L’établissement d’un serveur TCP implique les étapes de base suivantes:

  • Création d’une prise TCP avec un appel à prise().
  • Liant la prise au port d’écoute ( lier() ) Après avoir réglé le numéro de port.
  • Préparer la prise pour écouter les connexions (ce qui en fait une prise d’écoute), avec un appel à écouter() .
  • Accepter des connexions entrantes ( accepter() ). Cela bloque le processus jusqu’à ce qu’une connexion entrante soit reçue et renvoie un descripteur de socket pour la connexion acceptée. Le descripteur initial reste un descripteur d’écoute, et accepter() Peut être appelé à nouveau à tout moment avec cette prise, jusqu’à ce qu’elle soit fermée.
  • Communiquer avec l’hôte distant avec les fonctions API envoyer() et recv () , ainsi qu’avec les fonctions à usage général écrire() et lire() .
  • Clôture de chaque prise ouverte après utilisation avec la fonction fermer()

Le programme suivant crée un serveur TCP écoutant sur le numéro de port 1100:

 #inclure    #inclure    #inclure    #inclure    #inclure    #inclure    #inclure     #include 
  
  int main(void)
  {
    struct sockaddr_in sa;
    int SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (SocketFD == -1) {
      perror("cannot create socket");
      exit(EXIT_FAILURE);
    }
  
    memset(&sa, 0, sizeof sa);
  
    sa.sin_family = AF_INET;
    sa.sin_port = htons(1100);
    sa.sin_addr.s_addr = htonl(INADDR_ANY);
  
    if (bind(SocketFD,(struct sockaddr *)&sa, sizeof sa) == -1) {
      perror("bind failed");
      close(SocketFD);
      exit(EXIT_FAILURE);
    }
  
    if (listen(SocketFD, 10) == -1) {
      perror("listen failed");
      close(SocketFD);
      exit(EXIT_FAILURE);
    }
  
    for (;;) {
      int ConnectFD = accept(SocketFD, NULL, NULL);
  
      if (ConnectFD == -1) {
        perror("accept failed");
        close(SocketFD);
        exit(EXIT_FAILURE);
      }
  
      /* perform read write operations ... 
      read(ConnectFD, buff, size)
      */
  
      if (shutdown(ConnectFD, SHUT_RDWR) == -1) {
        perror("shutdown failed");
        close(ConnectFD);
        close(SocketFD);
        exit(EXIT_FAILURE);
      }
      close(ConnectFD);
    }

    close(SocketFD);
    return EXIT_SUCCESS;  
}

Client [ modifier ]]

La programmation d’une application client TCP implique les étapes suivantes:

  • Création d’une prise TCP.
  • Connexion au serveur ( connecter() ), en passant un sockaddr_in structure avec le sin_family mis à De_INET , Sin_port Défini sur le port, le point de terminaison est à l’écoute (dans l’ordre des octets de réseau) et sin_addr Défini sur l’adresse IP du serveur d’écoute (également dans l’ordre des octets réseau).
  • Communiquer avec l’hôte distant avec les fonctions API envoyer() et recv () , ainsi qu’avec les fonctions à usage général écrire() et lire() .
  • Clôture de chaque prise ouverte après utilisation avec la fonction fermer().
 #inclure    #inclure    #inclure    #inclure    #inclure    #inclure    #inclure     #include 
  
  int main(void)
  {
    struct sockaddr_in sa;
    int res;
    int SocketFD;

    SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (SocketFD == -1) {
      perror("cannot create socket");
      exit(EXIT_FAILURE);
    }
  
    memset(&sa, 0, sizeof sa);
  
    sa.sin_family = AF_INET;
    sa.sin_port = htons(1100);
    res = inet_pton(AF_INET, "192.168.1.3", &sa.sin_addr);

    if (connect(SocketFD, (struct sockaddr *)&sa, sizeof sa) == -1) {
      perror("connect failed");
      close(SocketFD);
      exit(EXIT_FAILURE);
    }
  
    /* perform read write operations ... */
  
    close(SocketFD);
    return EXIT_SUCCESS;
  }

Exemple de serveur client utilisant UDP [ modifier ]]

Le protocole de datagramme utilisateur (UDP) est un protocole sans connexion sans garantie de livraison. Les paquets UDP peuvent arriver hors service, plusieurs fois, ou pas du tout. En raison de cette conception minimale, l’UDP a considérablement moins de frais généraux que TCP. Être sans connexion signifie qu’il n’y a pas de concept de flux ou de connexion permanente entre deux hôtes. Ces données sont appelées Datagrams (Datagram Sockets).

L’espace d’adressage UDP, l’espace des numéros de port UDP (en terminologie ISO, le TSAPS), est complètement disjoint à partir de celui des ports TCP.

Serveur [ modifier ]]

Une application peut configurer un serveur UDP sur le numéro de port 7654 comme suit. Les programmes contient une boucle infinie qui reçoit des données de données UDP avec fonction recvfrom () .

#inclure   #inclure   #inclure   #inclure   #inclure   #inclure   #inclure  / * pour close () pour socket * /  #include 

int main(void)
{
  int sock;
  struct sockaddr_in sa; 
  char buffer[1024];
  ssize_t recsize;
  socklen_t fromlen;

  memset(&sa, 0, sizeof sa);
  sa.sin_family = AF_INET;
  sa.sin_addr.s_addr = htonl(INADDR_ANY);
  sa.sin_port = htons(7654);
  fromlen = sizeof sa;

  sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  if (bind(sock, (struct sockaddr *)&sa, sizeof sa) == -1) {
    perror("error bind failed");
    close(sock);
    exit(EXIT_FAILURE);
  }

  for (;;) {
    recsize = recvfrom(sock, (void*)buffer, sizeof buffer, 0, (struct sockaddr*)&sa, &fromlen);
    if (recsize < 0) {
      fprintf(stderr, "%sn", strerror(errno));
      exit(EXIT_FAILURE);
    }
    printf("recsize: %dn ", (int)recsize);
    sleep(1);
    printf("datagram: %.*sn", (int)recsize, buffer);
  }
}

Client [ modifier ]]

Ce qui suit est un programme client pour l’envoi d’un paquet UDP contenant la chaîne “Hello World!” Pour résoudre 127.0.0.1 au port numéro 7654.

#inclure   #inclure   #inclure   #inclure   #inclure   #inclure   #inclure   #include 
#include 

int main(void)
{
  int sock;
  struct sockaddr_in sa;
  int bytes_sent;
  char buffer[200];
 
  strcpy(buffer, "hello world!");
 
  /* create an Internet, datagram, socket using UDP */
  sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  if (sock == -1) {
      /* if socket failed to initialize, exit */
      printf("Error Creating Socket");
      exit(EXIT_FAILURE);
  }
 
  /* Zero out socket address */
  memset(&sa, 0, sizeof sa);
  
  /* The address is IPv4 */
  sa.sin_family = AF_INET;
 
   /* IPv4 addresses is a uint32_t, convert a string representation of the octets to the appropriate value */
  sa.sin_addr.s_addr = inet_addr("127.0.0.1");
  
  /* sockets are unsigned shorts, htons(x) ensures x is in network byte order, set the port to 7654 */
  sa.sin_port = htons(7654);
 
  bytes_sent = sendto(sock, buffer, strlen(buffer), 0,(struct sockaddr*)&sa, sizeof sa);
  if (bytes_sent < 0) {
    printf("Error sending packet: %sn", strerror(errno));
    exit(EXIT_FAILURE);
  }
 
  close(sock); /* close the socket */
  return 0;
}

Dans ce code, amortir est un pointeur vers les données à envoyer, et buffer_length Spécifie la taille des données.

Les références [ modifier ]]

Le de jure La définition standard de l’interface Sockets est contenue dans la norme POSIX, connue sous le nom de:

  • IEEE Std. 1003.1-2001 Standard pour les technologies de l’information – Interface du système d’exploitation portable (POSIX).
  • Norme technique en groupe ouvert: spécifications de base, numéro 6, décembre 2001.
  • ISO / IEC 9945: 2002

Des informations sur ce travail standard et en cours sont disponibles à partir de Le site Web d’Austin .

Les extensions IPv6 de l’API de socket de base sont documentées dans RFC 3493 et ​​RFC 3542.

Liens externes [ modifier ]]

after-content-x4