即使积压工作队列已满,客户端仍连接到TCP迭代服务器

即使积压工作队列已满,客户端仍连接到TCP迭代服务器,c,linux,sockets,tcp,C,Linux,Sockets,Tcp,这里是我创建的一个迭代服务器,用于处理基本的客户机-服务器聊天应用程序 我试图在终端窗口上运行TCPserver,在多个终端窗口上运行TCPclient 尽管我将服务器套接字中的backlog值(listensystem call)设置为5,但超过5个客户端正在连接(既没有被阻止也没有失败。它们立即connect成功) 我预计最多只能连接5个客户端(一次只接受1个) 我对listen系统调用中设置的backlog值的理解是否错误? 请澄清 int-listen(int-sockfd,int-ba

这里是我创建的一个迭代服务器,用于处理基本的客户机-服务器聊天应用程序

我试图在终端窗口上运行TCPserver,在多个终端窗口上运行TCPclient

尽管我将服务器套接字中的
backlog
值(
listen
system call)设置为5,但超过5个客户端正在连接(既没有被阻止也没有失败。它们立即
connect
成功)

我预计最多只能连接5个客户端(一次只接受1个)

我对
listen
系统调用中设置的backlog值的理解是否错误? 请澄清

int-listen(int-sockfd,int-backlog)

backlog参数定义sockfd的挂起连接队列可能增长到的最大长度

这里是实际的程序供参考

TCPserver.c
#包括
#包括
#包括
#包括
#包括
#包括
#定义待办事项5
#包括
#包括
#包括
int main()
{
//创建服务器套接字
国际标准差;
sd=套接字(AF_INET,SOCK_STREAM,0);
如果(sd==-1)
{
perror(“创建套接字时出错:”;
//将errno的值解释为错误消息,并将其打印到stderr
退出(退出失败);
}
其他的
printf(“已创建套接字!\n”);
//定义服务器地址
服务器地址中的结构sockaddr\u;
服务器地址.sin\u family=AF\u INET;
服务器地址sin端口=htons(9002);
server_address.sin_addr.s_addr=INADDR\u ANY;
//inet_addr(“192.168.137.163”);//INADDR_ANY;
//将套接字绑定到指定的IP和端口
int bind_status=bind(sd,(struct sockaddr*)和服务器地址,sizeof(服务器地址));
如果(绑定状态==-1)
{
perror(“绑定套接字时出错:”;
退出(退出失败);
}
其他的
printf(“绑定成功!\n”);
//倾听联系
int listen_status=listen(sd,BACKLOG);
如果(监听状态==-1)
{
perror(“侦听时出错:”);
退出(退出失败);
} 
其他的
printf(“服务器正在侦听!\n”);
而(1)
{
//接受连接并为此连接创建新套接字
国际新南威尔士大学sd;
客户端地址中的结构sockaddr\u;
int client_address_size=sizeof(client_address);
new_sd=accept(sd,(struct sockaddr*)和客户机地址,以及客户机地址大小);
如果(新的标准偏差==-1)
{
perror(“无法接受连接:”);
退出(退出失败);
}
其他的
printf(“接受成功!\n新客户端已连接。他将很快向您发送消息。\n(您可以聊天或说“退出”停止聊天)\n\n”);
//向客户端发送消息
char buffer[256]=“欢迎使用服务器,让我们聊天!\n(您可以聊天或说“退出”停止聊天)\n”;
发送(new_sd,buffer,sizeof(buffer),0);
//开始聊天
而(1)
{
memset(缓冲区,0256);
int n=recv(新的,缓冲区,大小f(缓冲区),0);
如果(n==-1 | | | strcmp(buffer,“exit”\n“==0 | | | strcmp(buffer,“exit”)==0)
打破
printf(“\n客户端说:%s\n”,缓冲区);
memset(缓冲区,0256);
printf(“说点什么”);
fgets(缓冲区,256,标准输入);
n=发送(新的\u sd,缓冲区,大小(缓冲区),0);
如果(n==-1 | | strcmp(缓冲区,“退出\n”)==0)
打破
}
//合上插座
关闭(新);;
printf(“\n连接已结束。正在等待新连接…\n”);
}
关闭(sd);
返回0;
}
这是客户

TCPclient.c
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main()
{
//创建套接字
int sd=套接字(AF_INET,SOCK_STREAM,0);
如果(sd==-1)
{
perror(“创建套接字时出错:”);
退出(退出失败);
}
其他的
printf(“已创建套接字!\n”);
//指定套接字的地址
服务器地址中的结构sockaddr\u;
服务器地址.sin\u family=AF\u INET;
服务器地址sin端口=htons(9002);
server_address.sin_addr.s_addr=inet_addr(“127.0.0.1”);//INADDR\u ANY;
//连接到服务器
int connection_status=connect(sd,(struct sockaddr*)和服务器地址,sizeof(服务器地址));
如果(连接状态==-1)
{
perror(“连接到远程套接字时出错:”);
退出(退出失败);
}
其他的
printf(“已连接到服务器!正在队列中等待服务器接受连接…\n”);
字符缓冲区[256];
//从服务器获取连接消息
recv(标准偏差和缓冲区),sizeof(缓冲区),0;
printf(“服务器说:%s\n”,缓冲区);
//开始聊天
而(1)
{
memset(缓冲区,0256);
printf(“说点什么”);
fgets(缓冲区,256,标准输入);
int n=send(sd,buffer,sizeof(buffer),0);
如果(n==-1 | | strcmp(缓冲区,“退出\n”)==0)
打破
memset(缓冲区,0256);
n=recv(sd,缓冲区,sizeof(缓冲区),0);
如果(n==-1 | | strcmp(缓冲区,“退出\n”)==0)
打破
printf(“\n服务器说:%s\n”,缓冲区);
}
//合上插座
关闭(sd);
返回0;
}
有人建议我检查我的系统上是否启用了
syncookies
。当我执行
cat/proc/sys/net/ipv4/tcp_-syncookies
时,我得到
1

积压的是“挂起的连接队列”--一旦你接受了一个连接,它就不再挂起,并从队列中退出,为另外5个挂起的连接留出空间

如果您想限制为5个连接,则需要计算您已接受(且未关闭)的连接数。任何更多的连接尝试都将在队列中等待。
#include<stdio.h>
#include<stdlib.h>

#include<sys/types.h>
#include<sys/socket.h>

#include<netinet/in.h>
#include<unistd.h>
#define BACKLOG 5

#include <netinet/in.h>
#include <arpa/inet.h>

#include<string.h>

int main()
{
    //create the server socket
    int sd;
    sd=socket(AF_INET,SOCK_STREAM,0);
    if(sd==-1)
    {
        perror("Some error occured in creating the socket: ");   
        //Interprets the value of errno as an error message, and prints it to stderr 
        exit(EXIT_FAILURE);
    }
    else
        printf("Socket created!\n");

    //define the server address
    struct sockaddr_in server_address;
    
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(9002);
    server_address.sin_addr.s_addr = INADDR_ANY; 
    //inet_addr("192.168.137.163");//INADDR_ANY;

    //bind the socket to our specified IP and port
    int bind_status = bind(sd, (struct sockaddr *) &server_address, sizeof(server_address));
    if(bind_status == -1)
    {
        perror("An error occurred in binding the socket: " );
        exit(EXIT_FAILURE);
    }
    else
        printf("Bind Successful!\n");


    //listen for connections
    int listen_status = listen(sd, BACKLOG);    
    if(listen_status == -1)
    {
        perror("Error occured in listening: ");
        exit(EXIT_FAILURE);
    } 
    else
        printf("Server is listening!\n");

    while(1)
    {
        //Accept a connection and create a new socket for this connection
        int new_sd;
        struct sockaddr_in client_address;
        int client_address_size = sizeof(client_address);

        new_sd= accept(sd, (struct sockaddr*) &client_address, &client_address_size);
        if(new_sd==-1)
        {
            perror("Can't accept connection: ");
            exit(EXIT_FAILURE);
        }
        else
            printf("Accept successful!\nA new client has connected. He'll soon send you a message.\n (You can chat or say \"exit\" to stop chatting)\n\n");
    

        //send a message to the client
        char buffer[256] = "Welcome to the server, lets chat! \n (You can chat or say \"exit\" to stop chatting)\n";
        send(new_sd,buffer,sizeof(buffer),0);

        //start chat
        while(1)
        {
            memset(buffer,0,256);
            int n = recv(new_sd, buffer, sizeof(buffer),0);
            if(n==-1 || strcmp(buffer,"exit\n")==0 || strcmp(buffer,"exit")==0)
                break;
            printf("\nclient said: %s\n",buffer);

            memset(buffer,0,256);
            printf("Say something: ");
            fgets(buffer,256,stdin);
            n = send(new_sd, buffer, sizeof(buffer), 0);
            if(n==-1 || strcmp(buffer,"exit\n")==0)
                break;
        }

        //close the sockets
        close(new_sd);
        printf("\nConnection ended. waiting for new connection now . . .\n");
    }

    close(sd);

    return 0;
}
#include<stdio.h>
#include<stdlib.h>

#include<sys/types.h>
#include<sys/socket.h>

#include<netinet/in.h>

#include<unistd.h>

#include <netinet/in.h>
#include <arpa/inet.h>
#include<string.h>
int main()
{
    //create the socket
    int sd = socket(AF_INET,SOCK_STREAM,0);

    if(sd==-1)
    {
        perror("Some error occurred in creating the socket: ");
        exit(EXIT_FAILURE);
    }
    else
        printf("Socket created!\n");

    //specify an address for the socket
    struct sockaddr_in server_address;
    
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(9002);
    server_address.sin_addr.s_addr = inet_addr("127.0.0.1");//INADDR_ANY;

    //Connect to the server
    int connection_status = connect(sd,(struct sockaddr *) &server_address, sizeof(server_address));

    if(connection_status == -1)
    {
        perror("There was an error connecting to the remote socket: ");
        exit(EXIT_FAILURE);
    }
    else
        printf("Connected to the server! Waiting in the queue for the server to accept the connection...\n");
        
    char buffer[256];
    //get the connection message from the server
    recv(sd, &buffer, sizeof(buffer), 0);
    printf("Server Said: %s\n", buffer);

    //start chat
    while(1)
    {
        memset(buffer,0,256);
        printf("Say something: ");
        fgets(buffer,256,stdin);
        int n = send(sd,buffer,sizeof(buffer),0);
        if(n==-1 || strcmp(buffer,"exit\n")==0)
            break;       

        memset(buffer,0,256);
        n = recv(sd,buffer,sizeof(buffer),0);
        if(n==-1 || strcmp(buffer,"exit\n")==0)
            break;

        printf("\nServer said: %s\n",buffer);
    }

    //close the socket
    close(sd);

    return 0;
}
accepting_thread () {
    int queue_count = 0;

    for (;;) {
        new_conn = accept();
        if (q_size(q) < 5) {
            q_enqueue(q, new_conn);
        } else {
            close(new_conn);
        }
    }
}

handling_thread () {
    for (;;) {
        new_conn = q_dequeue(q);
        /* ... */
        close(new_conn);
     }
}