O sistema connect()
e as bind()
chamadas 'associam' o descritor do arquivo de soquete a um endereço (normalmente uma combinação de ip / porta). Seus protótipos são como: -
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
e
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
Qual é a diferença exata entre 2 chamadas? Quando alguém deve usar connect()
e quando bind()
?
Especificamente, em alguns códigos de cliente de servidor de amostra, constatou que o cliente está usando connect()
e o servidor está usando a bind()
chamada. A razão não estava totalmente clara para mim.
c
sockets
network-programming
Siddhartha Ghosh
fonte
fonte
Respostas:
Para melhorar a compreensão, vamos descobrir onde exatamente ligar e conectar entra em cena,
Após o posicionamento de duas chamadas, conforme esclarecido por Sourav,
bind () associa o soquete ao seu endereço local [é por isso que o lado do servidor se liga, para que os clientes possam usar esse endereço para se conectar ao servidor.] connect () é usado para se conectar a um endereço [servidor] remoto, é por isso que é do lado do cliente , conectar [ler como: conectar ao servidor] é usado.
Não podemos usá-los de forma intercambiável (mesmo quando temos cliente / servidor na mesma máquina) devido a funções específicas e a implementação correspondente.
Recomendarei ainda correlacionar essas chamadas de handshake TCP / IP.
Então, quem enviará o SYN aqui, será o connect (). Enquanto bind () é usado para definir o ponto final da comunicação.
Espero que isto ajude!!
fonte
O liner:
bind()
para o próprio endereço,connect()
para o endereço remoto.Citando na página de manual de
bind()
e, do mesmo para
connect()
Esclarecer,
bind()
associa o soquete ao seu endereço local [é por isso que o lado do servidorbind
s, para que os clientes possam usar esse endereço para se conectar ao servidor.]connect()
é usado para conectar-se a um endereço [servidor] remoto, é por isso que é usado o lado do cliente, a conexão [leia como: conectar ao servidor].fonte
interchangeable
local
-> o próprio processo,remote
-> o outro processo.bind informa ao processo em execução para reivindicar uma porta. ou seja, ele deve se ligar à porta 80 e ouvir solicitações de entrada. com o bind, seu processo se torna um servidor. quando você usa o connect, você diz ao seu processo para conectar-se a uma porta que JÁ ESTÁ em uso. seu processo se torna um cliente. a diferença é importante: bind quer uma porta que não esteja em uso (para que possa reivindicá-la e se torne um servidor) e connect quer uma porta que já esteja em uso (para que possa se conectar a ela e conversar com o servidor)
fonte
Da Wikipedia: http://en.wikipedia.org/wiki/Berkeley_sockets#bind.28.29
conectar():
A chamada do sistema connect () conecta um soquete, identificado por seu descritor de arquivo, a um host remoto especificado pelo endereço desse host na lista de argumentos.
Certos tipos de soquetes são sem conexão, mais comumente soquetes de protocolo de datagrama do usuário. Para esses soquetes, a conexão assume um significado especial: o destino padrão para enviar e receber dados é definido no endereço fornecido, permitindo o uso de funções como send () e recv () em soquetes sem conexão.
connect () retorna um número inteiro que representa o código de erro: 0 representa sucesso, enquanto -1 representa um erro.
ligar():
bind () atribui um soquete a um endereço. Quando um soquete é criado usando socket (), ele recebe apenas uma família de protocolos, mas não recebe um endereço. Essa associação com um endereço deve ser realizada com a chamada do sistema bind () antes que o soquete possa aceitar conexões com outros hosts. bind () usa três argumentos:
sockfd, um descritor que representa o soquete para executar a ligação. my_addr, um ponteiro para uma estrutura sockaddr representando o endereço ao qual vincular. addrlen, um campo socklen_t que especifica o tamanho da estrutura sockaddr. Bind () retorna 0 em caso de sucesso e -1 se ocorrer um erro.
Exemplos: 1.) Usando o Connect
2.) Exemplo de ligação:
Espero que esclareça a diferença
Observe que o tipo de soquete que você declara dependerá do que você precisa, isso é extremamente importante
fonte
Eu acho que ajudaria sua compreensão se você pensar em
connect()
elisten()
como contrapartes, em vez deconnect()
ebind()
. A razão para isso é que você pode ligar ou omitirbind()
antes, embora raramente seja uma boa ideia chamá-lo antesconnect()
ou nãolisten()
.Se isso ajuda a pensar em termos de servidores e clientes, é
listen()
essa a marca registrada do primeiro econnect()
do segundo.bind()
pode ser encontrado - ou não encontrado - em ambos.Se assumirmos que nosso servidor e cliente estão em máquinas diferentes, fica mais fácil entender as várias funções.
bind()
atua localmente, ou seja, vincula o final da conexão na máquina em que é chamado, ao endereço solicitado e atribui a porta solicitada a você. Isso é feito independentemente da máquina ser um cliente ou servidor.connect()
inicia uma conexão com um servidor, ou seja, se conecta ao endereço e porta solicitados no servidor, a partir de um cliente. Esse servidor quase certamente já ligoubind()
anteslisten()
, para que você possa saber em qual endereço e porta se conectar a ele usandoconnect()
.Se você não ligar
bind()
, uma porta e um endereço serão implicitamente atribuídos e vinculados à máquina local quando você ligarconnect()
(cliente) oulisten()
(servidor). No entanto, esse é um efeito colateral de ambos, não da finalidade deles. Uma porta designada dessa maneira é efêmera.Um ponto importante aqui é que o cliente não precisa ser vinculado, porque os clientes se conectam aos servidores e, portanto, o servidor saberá o endereço e a porta do cliente, mesmo que você esteja usando uma porta efêmera, em vez de se vincular a algo específico. Por outro lado, embora o servidor possa ligar
listen()
sem chamarbind()
, nesse cenário eles precisariam descobrir a porta efêmera atribuída e comunicar isso a qualquer cliente que deseje se conectar a ela.Suponho que, como você mencionou,
connect()
esteja interessado em TCP, mas isso também é transferido para o UDP, onde não chamarbind()
antes do primeirosendto()
(o UDP é sem conexão) também faz com que uma porta e um endereço sejam atribuídos e vinculados implicitamente. Uma função que você não pode chamar sem ligação é arecvfrom()
que retornará um erro, porque sem uma porta atribuída e um endereço vinculado, não há nada a receber (ou muito, dependendo de como você interpreta a ausência de uma ligação).fonte
Demasiado longo; Não leia: a diferença é se a fonte (local) ou o endereço / porta de destino está sendo definido. Em resumo,
bind()
defina a fonte econnect()
o destino. Independentemente do TCP ou UDP.bind()
bind()
defina o endereço local (fonte) do soquete. Este é o endereço onde os pacotes são recebidos. Os pacotes enviados pelo soquete carregam isso como o endereço de origem, para que o outro host saiba para onde enviar seus pacotes.Se a recepção não for necessária, o endereço de origem do soquete é inútil. Protocolos como o TCP exigem o recebimento ativado para enviar corretamente, pois o host de destino envia uma confirmação quando um ou mais pacotes chegarem (ou seja, reconhecimento).
connect()
connect()
aciona o código TCP para tentar estabelecer uma conexão com o outro lado.connect()
defina apenas um endereço padrão para onde os pacotes serão enviados quando nenhum endereço for especificado. Quandoconnect()
não é usadosendto()
ousendmsg()
deve ser usado contendo o endereço de destino.Quando
connect()
uma função de envio ou é chamada e nenhum endereço é vinculado, o Linux vincula automaticamente o soquete a uma porta aleatória. Para detalhes técnicos, consulte oinet_autobind()
código-fonte do kernel do Linux.Notas laterais
listen()
é apenas TCP.struct sockaddr_in
) é composto por um endereço IP (consulte o cabeçalho IP ) e uma porta TCP ou UDP (consulte o cabeçalho TCP e UDP ).fonte