即使积压工作队列已满,客户端仍连接到TCP迭代服务器
这里是我创建的一个迭代服务器,用于处理基本的客户机-服务器聊天应用程序 我试图在终端窗口上运行TCPserver,在多个终端窗口上运行TCPclient 尽管我将服务器套接字中的即使积压工作队列已满,客户端仍连接到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
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);
}
}