Os arquivos sockets da Internet Unix são?

23

Eu entendo que "Tudo é um arquivo" é um dos principais conceitos do Unix, mas os sockets usam APIs diferentes que são fornecidas pelo kernel (como socket, sendto, recv, etc.), não como as interfaces normais do sistema de arquivos .

Como isso "Tudo é um arquivo" se aplica aqui?

    
por user3718463 07.11.2014 / 18:35

4 respostas

25

sockets use different APIs

Isso não é inteiramente verdade. Existem algumas funções adicionais para uso com soquetes, mas você pode usar, por exemplo,% normalread() e write() em um soquete fd.

how does this "Everything is a file" apply here?

No sentido de que um descritor de arquivo está envolvido.

Se a sua definição de "arquivo" é uma seqüência discreta de bytes armazenados em um sistema de arquivos, então nem tudo é um arquivo. No entanto, se a sua definição de arquivo é mais como: um canal para informações, ou seja, uma conexão de E / S, então "tudo é um arquivo" começa a fazer mais sentido. Essas coisas envolvem inevitavelmente sequências de bytes, mas de onde elas vêm ou vão podem diferir contextualmente.

Não é realmente pretendido literalmente, no entanto. Um daemon não é um arquivo, um daemon é um processo; mas se você estiver fazendo IPC , seu método de se relacionar com outro processo pode ser mitigado por entidades de estilo de arquivo.

    
por 07.11.2014 / 18:48
12

"Tudo é um arquivo" é apenas um exagero. Foi novela em 1970 e era uma característica distintiva primária do UNIX. Mas é apenas um conceito de marketing, não uma base real do UNIX, porque obviamente não é verdade. Não é benéfico ou sensato tratar TUDO como um arquivo.

A CPU é um arquivo? Seu programa lê () uma CPU para obter uma nova instrução? A RAM é um arquivo? O seu programa lê () o próximo byte?

Naquela época, havia tipos de sistema operacional que forneciam uma API para um disquete e uma API diferente para um disco rígido, uma API diferente para fita magnética e um monte de APIs diferentes para terminais diferentes e assim por diante. Os sistemas de mainframe da IBM tinham diferentes tipos de arquivos em discos rígidos e forneciam uma API diferente para cada um deles, acredite ou não! Assim, a abordagem UNIX "é um arquivo", junto com a abordagem "stdin / stdout / stderr", trouxe uma abstração muito elegante para usuários e programadores.

Com a rede, essa abstração específica simplesmente não deu certo. E não há mal, apenas um pouco menos elegância e coerência geral do sistema operacional. Mas isso funciona. Você vê um arquivo chamado /dev/myinternetz/www/google/com/tcp/80 em qualquer parte do seu sistema hoje? Você pode abrir (), escrever () uma consulta e ler () a resposta em HTML agradável? Não? Isso ocorre porque essa abstração "é um arquivo" não era muito útil para interagir na rede. Não funcionaria muito bem na prática. Lei de abstrações gotejantes em ação.

    
por 07.11.2014 / 20:05
7

Se você stat a socket, você verá que ele tem um número de inode e outras características de arquivos regulares, então eu classificaria como um arquivo no sistema de arquivos. Exemplo:

# 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. Informações adicionais para o Linux (ext3): Um socket tem um inode (que é um bloco de 256 bytes no disco) mas não possui nenhum bloco de dados (você pode verificar isso extraindo o inode e examinando os ponteiros de bloco de dados; ou executando o debugfs 'stat' que mostra um Contagem de blocos de 0). Então, ele tem metadados de arquivo (proprietário, grupo, permissões, etc), mas nenhum conteúdo de dados no disco. Isso é idêntico a um arquivo vazio regular ( touch /tmp/foo ) que também possui um valor de 0. No primeiro caso, o campo "type" no inode mostra "socket"; no segundo caso, mostra "arquivo regular".

Referências: ext2 inode structure ; Comandos stat , dumpe2fs e debugfs .

    
por 08.11.2014 / 00:48
6

Soquetes são arquivos. Você pode usar read e write em um soquete: eles são equivalentes a chamar recv e send com flags=0 . Você os fecha com close . Você pode movê-los com dup e amigos se precisar misturar os descritores de arquivos. Você pode definir alguns sinalizadores com fcntl e usar o armazenamento temporário stdio após chamar fdopen . A lista continua. Muito importante, você pode ligar para select e poll em qualquer tipo de arquivo, incluindo soquetes, para que estas funções permitam que um programa seja bloqueado até receber entrada por qualquer meio simplesmente listando descritores de arquivos.

Existem chamadas de sistema adicionais para alguns tipos de soquete ( recv e send , shutdown , etc.), como se houvesse uma chamada extra do sistema para dispositivos ( ioctl ).

Nem todos os arquivos têm nomes e, daqueles que o fazem, eles nem sempre vivem na estrutura do diretório. Pipes criados por pipe (por exemplo, em um pipeline de shell) e sockets criados por socketpair não tem nomes, mas ainda são arquivos. Sockets criados por socket têm um nome cuja sintaxe depende do domínio. Esse nome é passado em struct sockaddr para bind e outras funções. Para um soquete Unix ( AF_UNIX ), o nome é um struct sockaddr_un , que é uma família e uma string; dependendo da string, isso pode ser um nome de arquivo (os soquetes nomeados podem ser criados com mknod em muitas variantes unix) ou não (o namespace abstrato). Para um soquete IPv4 ( AF_INET ), o nome é um struct sockaddr_in , contendo um número de porta e endereço IP, mais o protocol da chamada socket .

    
por 09.11.2014 / 01:56