ソケットを使用して小さなプログラムサーバークライアントを作成しました。私はそれが何をする必要があるのか、そのバグについて説明します。サーバーは新しいクライアント(ソケット)ごとにスレッドを割り当てません
アプリケーションには、クライアントのためのサーバーの魔法使いがあります。同時に最大6クライアントをサポートします。各クライアントサーバーは、DETASH_STATEでスレッドを起動し、次に戻ってきます。
クライアントはファイルのコンテキストをサーバーに送信します。私は願っています
.txtの「任意のランダムな文字列を」__ft_:サーバがクライアントから送信されたコンテンツを受信するなどユニークな名前で、ファイルに保存します
を(私は行ごとに送信することを選択しました)今まではすべて明らかです。
バグ: もし私がクライアントを起動したら、20回言いましょう。サーバー側には20のファイルがありません。時々私は10、場合によっては12,5,7(予測不可能)を持っています。これは、3つまたは4つまたは5つのクライアント(ここでは私は3-4-5ファイルが必要です)によって送信されたコンテンツを1つのファイルに書き込みます。私はどこにバグがあるのか、何が間違っているのか分からない。追加情報が必要な場合は教えてください。
これは、サーバーのコード(その一部)である:(iの問題であり、ここではないと思います)
/**********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;
}
'create_random_name'関数が同じファイル名を1回以上生成しているかどうかを確認していません。 – Nadir
は同じ名前を生成することが可能で、それが同じファイルに書き込むのはなぜですか? –
可能性があります(その可能性は低いですが、そこにはあります)。既に存在するファイルの名前を返さないように変更してください。 – Nadir