2012-05-25 17 views
5

Según tengo entendido, cartera de pedidos determina el tamaño de la cola de conexión . Cualquier solicitud adicional que tenga un tamaño mayor en ese momento se cancelará (es esta declaración ¿no?).escucha() ignorando el valor de retraso acumulado

Ahora me tienen muy simple programa server.c

socket() 
bind() 
listen(..., 5) 
while(1) 
{ 
    accept() 
    read() 
    write() 
    sleep(3) 
    close() 
} 

Ahora, comienzo a 8 clientes a la vez para conectarse a este servidor. Sorprendentemente, el servidor sirve a todos los 8 clientes, pero en su lugar debe hacer cola solo a 5 clientes & restantes. Se deben rechazar 3 solicitudes de clientes. Otro punto interesante es que incluso si pongo este valor de acumulación como 0, el resultado sigue siendo el mismo. Luego intenté comentar la llamada a listen(), con esto se rechazaron las conexiones de los 8 clientes.

¿Alguien puede proporcionar alguna información sobre esto.

+0

Usted debe poner 'read',' 'write' y close' en un entorno concurrente. En su código, cuando la siguiente conexión es 'accept'ed parece que la anterior ya ha sido cerrada.Coloque el código en un hilo y asegúrese de que cada conexión dure lo suficiente para garantizar que realmente ocurran los 8 clientes que solicitan su servidor simultáneamente. –

+0

estaba probando ** backlog ** hace algún tiempo y no llegué a ninguna parte. espero ver respuestas ahora – tuxuday

+0

OP, puede publicar su código de muestra. para que la gente pueda copiarlo y pegarlo y probarlo. – tuxuday

Respuesta

2

El argumento de retraso es sugerencia sobre el tamaño de la cola. Entonces no puedes contar con que haga lo que estás preguntando.

listen()

Este answer parece cubrirlo.

Y más información, una cita de la página de escucha (2) el hombre en mi sistema Ubuntu:

El argumento atraso define la longitud máxima a la que puede crecer la cola de conexiones pendientes para sockfd. Si llega una solicitud de conexión cuando la cola está llena, , el cliente puede recibir un error con una indicación de ECONNREFUSED o, si el protocolo subyacente admite la retransmisión, la solicitud puede ignorarse para que un posterior vuelva a intentar la conexión.

Tenga en cuenta que dice "puede" en todas partes.

+0

En mi sistema, SOMAXCONN está configurado en 128. Entonces, ¿qué haría? sea ​​el comportamiento si comienzo más de 128 clientes a la vez. – user1409528

+0

Sí, la especificación dice que se admitirán valores de hasta 128, pero no existe la obligación de limitar realmente las conexiones pendientes. Y asumo que esta especificación es similar a lo que estás usando. –

+0

Ver la revisión de mi respuesta. –

0

he hecho hombre escucha en mi sistema & obtener la siguiente descripción:

DESCRIPCIÓN

escuchar() marca el zócalo mencionado por sockfd como una toma pasiva, es decir, como un socket que se ser utilizado para aceptar solicitudes de conexión entrantes usando accept (2). El argumento sockfd es un descriptor de archivo que hace referencia a un socket de tipo SOCK_STREAM o SOCK_SEQPACKET. El argumento de retraso define la longitud máxima a la que puede crecer la cola de conexiones pendientes para sockfd. Si llega una solicitud de conexión cuando la cola está llena, el cliente puede recibir un error con una indicación de ECONNREFUSED o, si el protocolo subyacente admite la retransmisión, la solicitud puede ignorarse para que se produzca un reintentos en la conexión.

+0

Nuevamente, tenga en cuenta el uso de la palabra "puede". No hay ningún requisito para respetar el retraso acumulado. –

+0

** Si llega una solicitud de conexión cuando la cola está llena, el cliente puede recibir un error con una indicación de ECONNREFUSED o, si el protocolo subyacente admite la retransmisión, la solicitud puede ignorarse para que vuelva a intentarse posteriormente en la conexión. ** Ok, quieres decir que puede rechazar las conexiones, pero en mi caso, solo está reintentando las conexiones más tarde. ¿¿derecho?? – user1409528

+0

Bueno, lo que probablemente está sucediendo en su caso es que está haciendo cola en la conexión. El punto es que no puedes depender de él para rechazar o poner en cola la conexión, porque eso no es lo que requiere la especificación de listen(). E incluso si funciona de cierta manera en alguna implementación, está sujeto a cambios en cualquier actualización futura, por lo que no debe depender de ella. –

0

Server.c

#include <sys/types.h> 
#include <sys/socket.h> 
#include <stdio.h> 
#include <sys/un.h> 
#include <unistd.h> 
int main() 
{ 
    int server_sockfd, client_sockfd; 
    int server_len, client_len; 
    struct sockaddr_un server_address; 
    struct sockaddr_un client_address; 

    unlink(“server_socket”); 
    server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0); 

    server_address.sun_family = AF_UNIX; 
    strcpy(server_address.sun_path, “server_socket”); 
    server_len = sizeof(server_address); 
    bind(server_sockfd, (struct sockaddr *)&server_address, server_len); 

    listen(server_sockfd, 5); 
    while(1) 
    { 
     char ch; 
     printf(“server waiting\n”); 

     client_len = sizeof(client_address); 
     client_sockfd = accept(server_sockfd,(struct sockaddr *)&client_address, &client_len); 

     read(client_sockfd, &ch, 1); 
     ch++; 
     write(client_sockfd, &ch, 1); 
sleep(3); 
     close(client_sockfd); 
    } 
} 

Client.c

#include <sys/types.h> 
#include <sys/socket.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/un.h> 
#include <unistd.h> 

int main() 
{ 
    int sockfd; 
    int len; 
    struct sockaddr_un address; 
    int result; 
    char ch = ‘A’; 

    sockfd = socket(AF_UNIX, SOCK_STREAM, 0); 

    address.sun_family = AF_UNIX; 
    strcpy(address.sun_path, “server_socket”); 
    len = sizeof(address); 

    result = connect(sockfd, (struct sockaddr *)&address, len); 
    if(result == -1) 
    { 
     perror(“oops: client1”); 
     exit(1); 
    } 

    write(sockfd, &ch, 1); 
    read(sockfd, &ch, 1); 
    printf(“char from server = %c\n”, ch); 
    close(sockfd); 
    exit(0); 
} 
Cuestiones relacionadas