Les fichiers de sockets Internet Unix sont-ils?

23

Je comprends que "Tout est un fichier" est l'un des principaux concepts d'Unix, mais les sockets utilisent différentes API fournies par le noyau (comme socket, sendto, recv, etc.), pas comme les interfaces normales du système de fichiers.

Comment ce "Tout est un fichier" s'applique-t-il ici?

user3718463
la source

Réponses:

26

les sockets utilisent différentes API

Ce n'est pas tout à fait vrai. Il existe quelques fonctions supplémentaires à utiliser avec les sockets, mais vous pouvez utiliser, par exemple, normal read()et write()sur un socket fd.

comment ce "Tout est un fichier" s'applique-t-il ici?

En ce sens qu'un descripteur de fichier est impliqué.

Si votre définition de «fichier» est une séquence discrète d'octets stockée dans un système de fichiers, alors tout n'est pas un fichier. Cependant, si votre définition de fichier ressemble davantage à un «conduit d'information», c'est-à-dire une connexion d'E / S - alors «tout est un fichier» commence à avoir plus de sens. Ces choses impliquent inévitablement des séquences d'octets, mais d'où elles viennent ou vont peuvent différer contextuellement.

Ce n'est pas vraiment destiné à la lettre, cependant. Un démon n'est pas un fichier, un démon est un processus; mais si vous faites IPC, votre méthode de relation avec un autre processus pourrait bien être atténuée par des entités de style de fichier.

boucle d'or
la source
5
Je dirais qu'une reformulation précise de "tout est un fichier" devrait être "toutes les interfaces passent par des fichiers". Vous interagissez avec les processus via des fichiers (stdin / out / err, / proc / $ pid, etc.). Vous interagissez avec le réseau via des fichiers (sockets / descripteurs de fichiers). Vous interagissez avec la souris via un fichier (/ dev / mouse).
Patrick
J'ai cloné une fois une poignée de socket en l'ouvrant depuis / proc.
Joshua
12

"Tout est un fichier" n'est qu'une surestimation. Il était nouveau dans les années 1970 et il a été une caractéristique distinctive primaire d'UNIX. Mais ce n'est qu'un concept marketing, pas une véritable fondation d'UNIX, car ce n'est évidemment pas vrai. Il n'est ni avantageux ni sensé de TOUT traiter comme un fichier.

Le CPU est-il un fichier? Votre programme lit-il () un CPU pour obtenir une nouvelle instruction? La RAM est-elle un fichier? Votre programme lit-il l'octet suivant?

À l'époque, il y avait des types de système d'exploitation qui vous donnaient une API pour une disquette et une API différente pour un disque dur, une API différente pour la bande magnétique et un tas d'API différentes pour différents terminaux et ainsi de suite. Les systèmes mainframe IBM avaient différents types de fichiers sur les disques durs et vous ont donné une API différente pour chacun d'eux, croyez-le ou non! L'approche UNIX "c'est un fichier", ainsi que l'approche "stdin / stdout / stderr", ont apporté une abstraction très élégante aux utilisateurs et aux programmeurs.

Avec le réseau, cette abstraction particulière n'a tout simplement pas fonctionné. Et il n'y a pas de mal, juste un peu moins d'élégance générale et de cohérence de l'OS. Mais ça marche. Voyez-vous un fichier appelé /dev/myinternetz/www/google/com/tcp/80n'importe où sur votre système aujourd'hui? Pouvez-vous l'ouvrir (), écrire () une requête et lire () la réponse en joli HTML? Non? En effet, cette abstraction "est un fichier" n'était pas très pratique pour interagir sur le réseau. Cela ne fonctionnerait pas trop bien dans la pratique. Loi des abstractions qui fuient en action.

kubanczyk
la source
9
Fait amusant: certaines versions de bash vous permettront d'ouvrir /dev/tcp/www.google.com/80. Ce n'est cependant pas un fichier réel - bash le simule.
user253751
2
@immibs: Plus précisément, il serait raisonnablement possible de créer un système de fichiers qui implémente réellement cela.
Joshua
Je suppose que vous pourriez lire /dev/memou /dev/kmemsi vous le vouliez.
Jason C
4
Notez que le plan 9 va plus loin et en effet, les protocoles réseau sont adressés via un pseudo système de fichiers à l'effet de votre exemple / dev / myinternetz / www / google / com / tcp / 80 (avec un chemin différent bien sûr). De plus, le ram physique fonctionne réellement comme un fichier, vous mmap ramez dans votre espace d'adressage virtuel comme vous y mappez un fichier. (malloc est implémenté sur cette idée).
Vality
1
Le plan 9 prenant "tout est un fichier" à l'extrême, en plus avec "tout est transparent sur le réseau" a des implications assez puissantes. Par exemple, il n'y a pas besoin de NAT, vous pouvez simplement monter la pile TCP / IP de votre routeur (qui est juste un fichier transparent (réseau)) sur votre machine locale et envoyer des paquets directement à partir de votre routeur.
Jörg W Mittag
7

Les sockets sont des fichiers. Vous pouvez utiliser readet writesur un socket: ils sont équivalents à appeler recvet sendavec flags=0. Vous les fermez avec close. Vous pouvez les déplacer avec dupet vos amis si vous avez besoin de mélanger les descripteurs de fichiers. Vous pouvez définir des indicateurs avec fcntlet utiliser la mise en mémoire tampon stdio après l'appel fdopen. La liste continue. Très important, vous pouvez appeler selectet pollsur n'importe quel type de fichier, y compris les sockets, de sorte que ces fonctions permettent à un programme de bloquer jusqu'à ce qu'il reçoive une entrée par n'importe quel moyen simplement en listant les descripteurs de fichier.

Il y a des appels système supplémentaires pour certains types de socket ( recvet send, shutdown, etc.), comme il y a un appel système supplémentaire pour les périphériques ( ioctl).

Tous les fichiers n'ont pas de nom , et parmi ceux qui le font, ils ne vivent pas toujours dans la structure du répertoire. Les tuyaux créés par pipe( par exemple dans un pipeline shell) et les sockets créés par socketpairn'ont pas de nom, mais ce sont toujours des fichiers. Les sockets créées par socketont un nom dont la syntaxe dépend du domaine. Ce nom est passé dans une struct sockaddrà bindet d'autres fonctions. Pour une AF_UNIXsocket Unix ( ), le nom est a struct sockaddr_un, qui est une famille et une chaîne; selon la chaîne, il peut s'agir d'un nom de fichier (les sockets nommées peuvent être créées avec mknodde nombreuses variantes unix) ou non (l'espace de noms abstrait). Pour une AF_INETsocket IPv4 ( ), le nom est un struct sockaddr_in, contenant un numéro de port et une adresse IP, plus le protocolde l' socketappel.

Gilles 'SO- arrête d'être méchant'
la source
7

Si vous êtes statun socket, vous verrez qu'il a un numéro d'inode et d'autres caractéristiques des fichiers normaux, donc je le classerais comme un fichier sur le système de fichiers. Exemple:

# file live
live: socket
# stat live
File: `live'
  Size: 0               Blocks: 0          IO Block: 4096   socket
Device: fc03h/64515d    Inode: 198817      Links: 1
Access: (0660/srw-rw----)  Uid: (23129/  icinga)   Gid: (23130/icinga-cmd)
Access: 2014-11-07 09:27:59.000000000 -0800
Modify: 2014-11-05 09:27:03.000000000 -0800
Change: 2014-11-05 09:27:03.000000000 -0800

11/17. Informations supplémentaires pour Linux (ext3): Un socket a un inode (qui est un bloc de 256 octets sur le disque) mais n'a pas de blocs de données (vous pouvez le vérifier en extrayant l'inode et en examinant les pointeurs de bloc de données; ou en exécutant debugfs 'stat' qui affiche un Blockcount de 0). Ainsi, il contient des métadonnées de fichier (propriétaire, groupe, autorisations, etc.) mais aucun contenu de données sur le disque. Ceci est identique à un fichier vide normal ( touch /tmp/foo) qui a également un nombre de blocs de 0. Dans le premier cas, le champ "type" dans l'inode affiche "socket"; dans le deuxième cas, il affiche "fichier normal".

Références: structure inode ext2 ; stat, dumpe2fsEt les debugfscommandes.

Michael Martinez
la source
1
Je dirais que le fait d'avoir quelque chose à exécuter fileou à utiliser staten fait un fichier.
Kevin