gpt4 book ai didi

c - 服务器不会为每个新客户端(套接字)分配线程

转载 作者:行者123 更新时间:2023-11-30 15:10:13 24 4
gpt4 key购买 nike

我使用套接字制作了一个小程序服务器客户端。我将解释它需要做什么,然后解释错误。

应用程序有一个等待客户端的服务器。它同时支持最多 6 个客户端。对于每个客户端服务器,在 DETASH_STATE 中启动一个线程,然后它返回并监听。

客户端将文件的上下文提交到服务器。 (我选择逐行发送)

服务器会接收客户端发送的内容,并将其保存到一个文件中,文件名称唯一,如:__ft_"任意随机字符串".txt

我希望到目前为止一切都清楚了。

错误:好吧,如果我启动客户端 20 次。在服务器端我没有 20 个文件。有时我有 10 个,有时 12、5、7(不可预测)。它将 3、4 或 5 个客户端发送的内容写入单个文件中(这里我需要有 3-4-5 个文件)。我不明白错误在哪里或者我做错了什么。如果您需要更多信息,请告诉我。

这是服务器代码(其中一部分):

/**********ASSING A PROTOCOL TO A SOCKET (BIND)************/

if(bind(sock_dest, (struct sockaddr *)&server,sizeof (server))<0)
{
printf("Bind failed\n");
return 1;
}

/**********************************************************/

/*************** LISTEN FOR CONNECTIONS ********************/

listen(sock_dest,6);
printf("Waiting for connections\n");

/**********************************************************/


/****ACCEPT CONNECTION AND MAKE ATHREAD FOR EVERY CLIENT***/
c = sizeof ( struct sockaddr_in);
pthread_t thread_id;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);

while( ( client_socket = accept( sock_dest, ( struct sockaddr *)&client, (socklen_t *) &c)) )
{
printf("Connection accepted.\n");

if(client_socket < 0)
{
printf("Accepting connection failed.\n");
return 1;
}

if(pthread_create( &thread_id, &attr, connection_handler, (void*) &client_socket ) < 0)
{
printf("Couldn't create a thread for the new client.\n");
return 1;
}
else
printf("Handler assigned\n");
}




return 0;
}


void *connection_handler (void *socket_dest)
{
char *dest_file_name;
char buffer[300];
int sock = *( int *) socket_dest;
char *exit_signal="EXIT";

if((dest_file_name=create_random_name())==NULL)
{
printf("Generating a random name failed\n");
return NULL;
}

int i=0;
while(1)
{
while(i<299)
{
recv(sock,buffer+i,1,0);
if(buffer[i]=='\n')
{
i=0; // setting i to 0 because next time when we read a path(string) it need to be stored from 0 pozition in array.
break;
}
++i;
}

if((strcmp(buffer,exit_signal))==0)
{
printf("Exit signal received.\n");
return NULL;
}

if((write_line_in_file(buffer,dest_file_name))==1)
{
printf("Failed to write one of the lines in %s\n",dest_file_name);
}


printf("Linie primita:%s\n",buffer);

bzero(buffer,256); // put all bytes to 0 from buffer
}

return 0;
}



char *create_random_name(void)
{
const char charset[] = "abcdefghijklmnopqrstuvwxyz";
char *file_name;
int i=0;
int key;
struct stat stbuf;
time_t t;

while(1)
{

srand((unsigned) time(&t));

if((file_name = malloc(16 * sizeof ( char )) ) == NULL)
{
printf("Failed to alloc memory space\n");
return NULL;
}
strcpy(file_name,"__ft_");
for(i=5 ; i<11 ; i++)
{
key = rand() % (int)(sizeof(charset)-1);
file_name[i]=charset[key];
}
strcat(file_name,".txt");
file_name[15] = '\0';
if(stat(file_name,&stbuf)==-1)
{
break;
}
}
return file_name;
}

/************* RETURN 0 IF SUCCES AND 1 IF FAILS ***********/

int write_line_in_file(char *line,char *file_name)
{
FILE *file;
if((file=fopen(file_name, "a")) == NULL)
{
printf("Can't open %s.\n");
return 1;
}
fprintf(file,"%s",line);
fclose(file);
return 0;
}

这是客户端代码(我认为这不是问题):

#include <stdio.h>
#include <stdlib.h>
#include<netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>




int main(int argc, char *argv[])
{
/***************CHECKING THE ARGUMENT*************/
if (argc < 2)
{
printf("Usage: %s hostname\n", argv[0]);
return 1;
}
/*************************************************/

int sock_dest;
struct sockaddr_in server_addr;
char line[300];

/******************CREATE SOCKET*****************/

sock_dest = socket(AF_INET, SOCK_STREAM, 0);
if(sock_dest == -1)
{
printf("Couldn't create socket.\n");
return 1;
}

struct hostent *server;
server = gethostbyname(argv[1]);

if (server == NULL)
{
printf("ERROR, no such host\n");
return 1;
}

/***** SETTING FIELDS OF SERVER SOCKADDR_IN STRUCTURE *****/

bzero((char *) &server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,(char *)&server_addr.sin_addr.s_addr,server->h_length);
server_addr.sin_port = htons ( 31000 );

/**********************************************************/

/*********TRYING TO CONNECT TO THE SERVER******************/


if (connect(sock_dest,(struct sockaddr *) &server_addr,sizeof(server_addr)) < 0)
{
printf("ERROR:(Can't connect to the server. Please check if it's online)\n");
return 1;
}

/***********************************************************/

char path_read[200];
int read_len,n;
FILE *f_read;
char *exit_signal = "\nEXIT\0";
if((f_read=fopen("test.txt","r"))==NULL)
{
printf("Failed to open path.txt.\n");
return 0;
}
while((fgets(path_read,200,f_read))!=NULL)
{
path_read[strlen(path_read)+1]='\n';
n = write(sock_dest,path_read,strlen(path_read));
if(n<0)
error("ERROR writing to socket");
bzero(path_read,200);
}

n=write(sock_dest,exit_signal,strlen(exit_signal));
fclose(f_read);
close(sock_dest);
printf("All lines in the file were sent to the server.\nExiting...\n");

return 0;
}

最佳答案

这是一个错误:

(void*) &client_socket

首先,不需要转换为void*。其次,它看起来像 client_socket 是一个局部变量,您将其地址作为上下文传递给线程。在起始线程中,您可以继续在下一次迭代中覆盖其值。

关于c - 服务器不会为每个新客户端(套接字)分配线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36302239/

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