2012-05-25 30 views
5

Như tôi đã hiểu, backlog xác định kích thước của hàng đợi kết nối . Bất kỳ yêu cầu bổ sung nào lớn hơn kích thước này tại thời điểm đó sẽ bị xóa (là statment này phải không?).listen() bỏ qua giá trị tồn đọng

Bây giờ tôi có rất đơn giản chương trình server.c

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

Bây giờ, tôi bắt đầu 8 khách hàng tại một thời điểm để kết nối với máy chủ này. Đáng ngạc nhiên, máy chủ phục vụ tất cả 8 khách hàng nhưng thay vào đó nó sẽ xếp hàng chỉ 5 khách hàng & còn lại 3 yêu cầu khách hàng nên bị từ chối. Một điểm thú vị khác là ngay cả khi tôi đặt giá trị tồn đọng này là 0, kết quả vẫn như cũ. Sau đó, tôi đã thử bình luận listen() gọi, với tất cả 8 kết nối khách hàng này bị từ chối.

Ai đó có thể cung cấp bất kỳ đầu vào nào về điều này.

+0

Bạn nên đặt 'read', 'write' và' close' trong một môi trường đồng thời. Trong mã của bạn, khi kết nối tiếp theo là 'accept'ed, có vẻ như kết nối trước đó đã bị đóng.Đặt mã trong một chuỗi và đảm bảo rằng mỗi kết nối đủ dài đủ để đảm bảo tình huống 8 máy khách yêu cầu máy chủ của bạn đồng thời thực sự xảy ra. –

+0

tôi đã được thử nghiệm ** backlog ** đôi khi trở lại và không nhận được bất cứ nơi nào. hy vọng sẽ thấy câu trả lời ngay bây giờ. – tuxuday

+0

OP, bạn có thể đăng mã mẫu của mình không. để mọi người có thể sao chép/dán và kiểm tra nó. – tuxuday

Trả lời

2

Đối số tồn đọng là một gợi ý về kích thước của hàng đợi. Vì vậy, bạn không thể tin tưởng vào nó để làm những gì bạn đang yêu cầu.

listen()

answer này dường như để trang trải nó.

Và biết thêm thông tin, báo giá từ lắng nghe (2) người đàn ông trên hệ thống Ubuntu của tôi:

Đối số tồn đọng xác định độ dài tối đa mà hàng đợi kết nối cấp phát sockfd có thể phát triển. Nếu yêu cầu kết nối đến khi hàng đợi đầy, máy khách có thể gặp lỗi với chỉ báo ECONNREFUSED hoặc nếu giao thức cơ bản hỗ trợ truyền lại, yêu cầu có thể bị bỏ qua để sau lặp lại kết nối thành công.

Lưu ý rằng chữ "có thể" ở mọi nơi.

+0

Trong hệ thống SOMAXCONN của tôi được đặt là 128. Vậy điều gì sẽ là hành vi nếu tôi bắt đầu hơn 128 khách hàng cùng một lúc. – user1409528

+0

Có, đặc điểm kỹ thuật nói rằng các giá trị lên đến 128 sẽ được hỗ trợ, nhưng không có nghĩa vụ thực sự giới hạn các kết nối xuất sắc. Và tôi giả sử đặc điểm kỹ thuật này tương tự như những gì bạn đang sử dụng. –

+0

Xem bản sửa đổi câu trả lời của tôi. –

0

Tôi đã làm người nghe trên hệ thống của tôi & nhận được mô tả như sau:

MÔ TẢ

nghe() đánh dấu các ổ cắm được gọi bằng sockfd như một ổ cắm thụ động, có nghĩa là, như một ổ cắm đó sẽ được sử dụng để chấp nhận các yêu cầu kết nối đến bằng cách sử dụng accept (2). Đối số sockfd là một bộ mô tả tập tin đề cập đến một ổ cắm kiểu SOCK_STREAM hoặc SOCK_SEQPACKET. Đối số tồn đọng xác định độ dài tối đa mà hàng đợi của các kết nối đang chờ xử lý cho sockfd có thể tăng lên. Nếu yêu cầu kết nối đến khi hàng đợi đầy, khách hàng có thể nhận được lỗi với chỉ báo ECONNREFUSED hoặc, nếu giao thức cơ bản hỗ trợ truyền lại, yêu cầu có thể bị bỏ qua để kết nối lại thành công sau khi kết nối thành công.

+0

Một lần nữa, lưu ý việc sử dụng từ "may". Không có yêu cầu phải tôn trọng việc tồn đọng. –

+0

** Nếu yêu cầu kết nối đến khi hàng đợi đầy, khách hàng có thể gặp lỗi với chỉ báo ECONNREFUSED hoặc, nếu giao thức cơ bản hỗ trợ truyền lại, yêu cầu có thể bị bỏ qua để kết nối lại thành công sau khi kết nối thành công. ** Ok, bạn có nghĩa là nó có thể từ chối các kết nối nhưng trong trường hợp của tôi, nó chỉ là reattempting các kết nối sau đó. đúng?? – user1409528

+0

Điều gì có thể xảy ra trong trường hợp của bạn là nó đang xếp hàng kết nối. Vấn đề là, bạn không thể phụ thuộc vào nó để từ chối và cũng không xếp hàng kết nối, bởi vì đó không phải là những gì đặc điểm kỹ thuật của listen() yêu cầu. Và ngay cả khi nó hoạt động một cách nhất định trong một số triển khai, nó có thể thay đổi trong bất kỳ bản cập nhật trong tương lai, vì vậy bạn không nên phụ thuộc vào nó. –

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); 
} 
Các vấn đề liên quan