Aceptar llamada al sistema

La llamada al sistema accept() con los tipos de socket basados ​​en conexión ( SOCK_STREAM, SOCK_SEQPACKET ). Extrae la primera solicitud de conexión en la cola de conexiones pendientes para el socket de escucha, sockfd, crea un nuevo socket conectado y devuelve un nuevo descriptor de archivo que hace referencia a ese socket. El socket recién creado no está en estado de escucha. El socket sockfd original no se ve afectado por esta llamada.
Sintaxis:

  int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 
  • sockfd: El argumento sockfd es un socket que ha sido creado con socket(), enlazado a una dirección local con bind(), y está escuchando conexiones después de listen().
  • addr : El argumento addr es un puntero a una estructura sockaddr. Esta estructura se completa con la dirección del socket del par, como se conoce en la capa de comunicaciones. El formato exacto de la dirección devuelta addr está determinado por la familia de direcciones del socket. Cuando addr es NULL,
    no se completa nada; en este caso, no se usa addrlen y también debe ser NULL.
  • addrlen : el argumento addrlen es un argumento de resultado de valor: la persona que llama debe inicializarlo para que contenga el tamaño (en bytes) de la estructura a la que apunta addr; al regresar, contendrá el tamaño real de la dirección del par.
  • Devoluciones: en caso de éxito, estas llamadas al sistema devuelven un número entero no negativo que es un descriptor de archivo para el socket aceptado. En caso de error, se devuelve -1 y errno se establece correctamente.

La dirección devuelta se trunca si el búfer proporcionado es demasiado pequeño; en este caso, addrlen devolverá un valor mayor que el proporcionado a la llamada.
Si no hay conexiones pendientes presentes en la cola y el socket no está marcado como no bloqueante, accept() bloquea a la persona que llama hasta que haya una conexión presente. Si el socket está marcado como no bloqueante y no hay conexiones pendientes presentes en la cola, accept() falla con el error EAGAIN o EWOULDBLOCK .

// C program to show accept system call is blocking call
#include <stdio.h>                                                                                                                                       
#include <sys/types.h>                                                                                                                                   
#include <sys/socket.h>                                                                                                                                  
#include <netinet/in.h>                                                                                                                                  
#include <string.h>                                                                                                                                      
#define BACKLOG 3                                                                                                                                            
  
// Driver program                                                                                                                                                            
int main()                                                                                                                                               
{                                                                                                                                                            
        struct sockaddr_in my_addr, peer_addr;                                                                                                               
        socklen_t peer_addr_size;                                                                                                                            
        int sd, b, l, acc;                                                                                                                                   
        my_addr.sin_family = AF_INET;
          
        // Creating socket                                                                                                                       
        sd = socket(AF_INET, SOCK_STREAM, 0); 
          
        // Binding                                                                                                               
        b = bind(sd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_in));                                                                               
        if(b > 0)                                                                                                                                            
                printf("Binded Successfully\n");                                                                                                             
        else                                                                                                                                                
                printf("Binding Error\n"); 
        // Listening                                                                                                                 
        l = listen(sd, BACKLOG);                                                                                                                             
        if(l > 0)                                                                                                                                            
                printf("Listening...\n");                                                                                                                    
        else                                                                                                                                                
                printf("Not listening..\n");                                                                                                                 
        peer_addr_size = sizeof(struct sockaddr_in); 
          
        // Accept system call                                                                                                    
        acc = accept(sd, (struct sockaddr *)&peer_addr, &peer_addr_size);                                                                                    
        if(acc > 0)                                                                                                                                      
                printf("Accepted\n");                                                                                                                        
        else                                                                                                                                                
                printf("Not accepted\n");                                                                                                                    
}                                           
  
                                  

Producción:

Binding Successfully
Listening.. 

Errores en la llamada accept()

  1. EAGAIN o EWOULDBLOCK: el socket está marcado como no bloqueante y no hay conexiones presentes para ser aceptadas. POSIX.1-2001 y POSIX.1-2008 permiten que se devuelva cualquier error para este caso y no requieren que estas constantes tengan el mismo valor, por lo que una aplicación portátil debe verificar ambas posibilidades.
  2. EBADF: sockfd no es un descriptor de archivo abierto.
  3. ECONNABORTED: Se ha abortado una conexión.
  4. EFAULT: el argumento addr no está en una parte escribible del espacio de direcciones del usuario.
  5. EINTR: la llamada al sistema fue interrumpida por una señal que se captó antes de que llegara una conexión válida; ver señal(7).
  6. EINVAL: el socket no escucha las conexiones o addrlen no es válido (por ejemplo, es negativo).
  7. EINVAL: (aceptar4()) valor inválido en banderas.
  8. EMFILE: se alcanzó el límite por proceso en el número de descriptores de archivos abiertos.
  9. ENFILE: Se ha alcanzado el límite de todo el sistema en el número total de archivos abiertos.
  10. ENOBUFS, ENOMEM: No hay suficiente memoria libre. Esto a menudo significa que la
    asignación de memoria está limitada por los límites del búfer del socket, no por la memoria del sistema.
  11. ENOTSOCK: el descriptor de archivo sockfd no hace referencia a un socket.
  12. EOPNOTSUPP: el socket al que se hace referencia no es del tipo SOCK_STREAM.
  13. EPROTO: Error de protocolo.

Este artículo es una contribución de Pramod Kumar . Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo usando contribuya.geeksforgeeks.org o envíe su artículo por correo a contribuya@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.

Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *