gpt4 book ai didi

c++ - 许多 linux 套接字后服务器卡住

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:53:10 24 4
gpt4 key购买 nike

我在 linux 上用 c 语言开发了一个 tcp 服务器。我注意到如果我在服务器上建立压力连接(在我的网络浏览器上用“F5”不断刷新服务器地址),那么我的服务器将被卡住。

我检查了 netstat 命令,我发现服务器上打开了很多这样的套接字:

tcp        0      0 192.168.1.211:7547      192.168.1.133:10073     TIME_WAIT
tcp 0 0 192.168.1.211:7547 192.168.1.133:9985 TIME_WAIT
tcp 0 0 192.168.1.211:7547 192.168.1.133:9967 TIME_WAIT
tcp 0 0 192.168.1.211:7547 192.168.1.133:10041 TIME_WAIT
tcp 0 0 192.168.1.211:7547 192.168.1.133:10027 TIME_WAIT
tcp 0 0 192.168.1.211:7547 192.168.1.133:10042 TIME_WAIT
tcp 0 0 192.168.1.211:7547 192.168.1.133:10016 TIME_WAIT
tcp 0 0 192.168.1.211:7547 192.168.1.133:9993 TIME_WAIT

在我的服务器代码中,我已经使用 close() 关闭了套接字。即使我关闭服务器,这些套接字仍保持打开状态。如果我重新启动它,然后 bind() 返回错误(我认为这是因为套接字没有完全关闭)。

如何解决这个问题?

即使有连接压力,我怎样才能让我的服务器不被卡住?

如何强制快速关闭,以便在重新启动服务器时不会在 bind() 中出现错误?

代码:

#include<stdio.h>
#include<string.h> //strlen
#include<stdlib.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
#include<pthread.h> //for threading , link with lpthread

struct http_cr_data {
int client;
int count;
};

void *thread_serv_new_client(void *v)
{
int count;
int client;
struct http_cr_data *crd = (struct http_cr_data *)v;
count = crd->count;
client = crd->client;
free(crd);

printf("(%d) Received message by the server!\n", count);
close(client);
return NULL;
}

void server_init(void)
{
int socket_desc , client_sock , c, count=0 , *new_sock;
struct sockaddr_in server , client;

for(;;) {
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf ("Could not open server socket for Connection Requests, Trying again");
sleep(1);
continue;
}

//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(7547);

//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
printf ("Could not bind server socket for Connection Requests, Trying again");
sleep(1);
continue;
}
break;
}

printf ("Connection Request server initiated");

//Listen
listen(socket_desc , 3);

//Accept and incoming connection
c = sizeof(struct sockaddr_in);
while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
pthread_t serv_cr__thread;
struct http_cr_data *crd = malloc(sizeof (struct http_cr_data));
crd->count = ++count;
crd->client = client_sock;

int error = pthread_create(&serv_cr__thread, NULL, &thread_serv_new_client, (void *)crd);
if (error<0)
{
printf ("Error when creating Connection Request thread!");
}
}

if (client_sock < 0)
{
printf ("Could not accept connections for Connection Requests!");
return;
}
}

int main() {
server_init();
return 0;
}

最佳答案

您可能想要分离正在创建的线程。

目前线程没有分离,这意味着当它们退出时,它们的相关资源将不会被释放(直到加入,你不做的事情)并且这将耗尽你的机器资源(这里:内存)。

要分离线程,您可以在线程函数的最开始调用 pthread_detach():

void *thread_serv_new_client(void *v)  
{
pthread_detach(pthread_self());

关于重新启动服务器时遇到的绑定(bind)错误,您可能想阅读以下问题的答案:What is the meaning of SO_REUSEADDR (setsockopt option) - Linux?关于套接字选项 SO_REUSEADDR 的使用。

关于c++ - 许多 linux 套接字后服务器卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26057260/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com