Ambos connect()
y bind()
sistema de llamadas 'asociado' el descriptor de archivo de socket a una dirección (típicamente un / combinación de puerto IP). Sus prototipos son como: -
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
y
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
¿Cuál es la diferencia exacta entre 2 llamadas? ¿Cuándo se debe usar connect()
y cuándo bind()
?
Específicamente, en algunos códigos de cliente de servidor de muestra, se encontró que el cliente está usando connect()
y el servidor está usando la bind()
llamada. La razón no me quedó del todo clara.
c
sockets
network-programming
Siddhartha Ghosh
fuente
fuente
Respuestas:
Para mejorar la comprensión, averigüemos dónde entra exactamente enlazar y conectar,
Además del posicionamiento de dos llamadas, como aclaró Sourav,
bind () asocia el socket con su dirección local [es por eso que el lado del servidor se une, para que los clientes puedan usar esa dirección para conectarse al servidor]. connect () se usa para conectarse a una dirección de [servidor] remota, por eso es del lado del cliente , se utiliza conectar [leer como: conectar al servidor].
No podemos usarlos indistintamente (incluso cuando tenemos cliente / servidor en la misma máquina) debido a roles específicos y la implementación correspondiente.
Además, recomendaré correlacionar estas llamadas con el protocolo de enlace TCP / IP.
Entonces, quién enviará SYN aquí, será connect (). Mientras que bind () se usa para definir el punto final de la comunicación.
¡¡Espero que esto ayude!!
fuente
La única línea:
bind()
dirección propia,connect()
dirección remota.Citando de la página de manual de
bind()
y, de lo mismo para
connect()
Para aclarar,
bind()
asocia el socket con su dirección local [es por eso que el lado del servidorbind
es, para que los clientes puedan usar esa dirección para conectarse al servidor].connect()
se usa para conectarse a una dirección de [servidor] remoto, por eso se usa el lado del cliente, conectar [leer como: conectarse al servidor].fuente
interchangeable
local
-> el proceso en sí,remote
-> el otro proceso.bind le dice al proceso en ejecución que reclame un puerto. es decir, debe vincularse al puerto 80 y escuchar las solicitudes entrantes. con bind, su proceso se convierte en un servidor. cuando usa connect, le dice a su proceso que se conecte a un puerto que YA está en uso. su proceso se convierte en cliente. la diferencia es importante: bind quiere un puerto que no está en uso (para poder reclamarlo y convertirse en un servidor), y connect quiere un puerto que ya está en uso (para poder conectarse a él y hablar con el servidor)
fuente
De Wikipedia http://en.wikipedia.org/wiki/Berkeley_sockets#bind.28.29
conectar():
La llamada al sistema connect () conecta un conector, identificado por su descriptor de archivo, a un host remoto especificado por la dirección de ese host en la lista de argumentos.
Ciertos tipos de sockets no tienen conexión, más comúnmente sockets de protocolo de datagramas de usuario. Para estos sockets, connect adquiere un significado especial: el destino predeterminado para enviar y recibir datos se establece en la dirección dada, lo que permite el uso de funciones como send () y recv () en sockets sin conexión.
connect () devuelve un número entero que representa el código de error: 0 representa éxito, mientras que -1 representa un error.
enlazar():
bind () asigna un socket a una dirección. Cuando se crea un socket usando socket (), solo se le da una familia de protocolos, pero no se le asigna una dirección. Esta asociación con una dirección debe realizarse con la llamada al sistema bind () antes de que el socket pueda aceptar conexiones con otros hosts. bind () toma tres argumentos:
sockfd, un descriptor que representa el socket para realizar el enlace. my_addr, un puntero a una estructura sockaddr que representa la dirección a la que enlazar. addrlen, un campo socklen_t que especifica el tamaño de la estructura sockaddr. Bind () devuelve 0 en caso de éxito y -1 si se produce un error.
Ejemplos: 1.) Uso de Connect
2.) Ejemplo de enlace:
Espero que aclare la diferencia
Tenga en cuenta que el tipo de enchufe que declare dependerá de lo que necesite, esto es extremadamente importante
fuente
Creo que ayudaría a su comprensión si piensa en
connect()
ylisten()
como contrapartes, en lugar deconnect()
ybind()
. La razón de esto es que puede llamar u omitirbind()
antes de cualquiera de ellos, aunque rara vez es una buena idea llamarlo antesconnect()
o no llamarlo anteslisten()
.Si ayuda pensar en servidores y clientes, es
listen()
cuál es la seña de identidad de los primeros y deconnect()
los segundos.bind()
se puede encontrar, o no encontrar, en cualquiera.Si asumimos que nuestro servidor y cliente están en máquinas diferentes, será más fácil comprender las distintas funciones.
bind()
actúa localmente, es decir, vincula el final de la conexión en la máquina en la que se llama, a la dirección solicitada y le asigna el puerto solicitado. Lo hace independientemente de si esa máquina será un cliente o un servidor.connect()
inicia una conexión a un servidor, es decir, se conecta a la dirección solicitada y al puerto en el servidor, desde un cliente. Es casi seguro que ese servidor habrá llamadobind()
anteslisten()
, para que pueda saber en qué dirección y puerto conectarse con el usoconnect()
.Si no llama
bind()
, un puerto y una dirección se asignarán implícitamente y se vincularán en la máquina local cuando llame aconnect()
(cliente) olisten()
(servidor). Sin embargo, ese es un efecto secundario de ambos, no su propósito. Un puerto asignado de esta manera es efímero.Un punto importante aquí es que el cliente no necesita estar vinculado, porque los clientes se conectan a los servidores, por lo que el servidor conocerá la dirección y el puerto del cliente aunque esté usando un puerto efímero, en lugar de vincularse a algo específico. Por otro lado, aunque el servidor podría llamar
listen()
sin llamarbind()
, en ese escenario necesitarían descubrir su puerto efímero asignado y comunicarlo a cualquier cliente que quiera conectarse a él.Supongo que, como mencionas
connect()
, estás interesado en TCP, pero esto también se traslada a UDP, donde no llamarbind()
antes de la primerasendto()
(UDP no tiene conexión) también hace que un puerto y una dirección se asignen y enlacen implícitamente. Una función a la que no se puede llamar sin vinculación esrecvfrom()
, que devolverá un error, porque sin un puerto asignado y una dirección vinculada, no hay nada que recibir (o demasiado, dependiendo de cómo interprete la ausencia de una vinculación).fuente
Demasiado largo; No leer: la diferencia es si se establece la dirección / puerto de origen (local) o de destino. En resumen,
bind()
configure la fuente yconnect()
el destino. Independientemente de TCP o UDP.bind()
bind()
establece la dirección local (fuente) del socket. Esta es la dirección donde se reciben los paquetes. Los paquetes enviados por el socket llevan esto como la dirección de origen, por lo que el otro host sabrá dónde enviar sus paquetes.Si la recepción no es necesaria, la dirección de origen del socket es inútil. Los protocolos como TCP requieren que la recepción esté habilitada para enviar correctamente, ya que el host de destino envía una confirmación cuando han llegado uno o más paquetes (es decir, acuse de recibo).
connect()
connect()
activa el código TCP para intentar establecer una conexión con el otro lado.connect()
solo establezca una dirección predeterminada a donde se envían los paquetes cuando no se especifica ninguna dirección. Cuandoconnect()
no se usa,sendto()
osendmsg()
debe usarse que contiene la dirección de destino.Cuando
connect()
se llama a una función de envío y no hay ninguna dirección vinculada, Linux vincula automáticamente el socket a un puerto aleatorio. Para obtener detalles técnicos, consulte elinet_autobind()
código fuente del kernel de Linux.Notas al margen
listen()
es solo TCP.struct sockaddr_in
) está compuesta por una dirección IP (ver encabezado IP ) y un puerto TCP o UDP (ver encabezado TCP y UDP ).fuente