2016-03-30 6 views
0

Ich habe einen kleinen Programm-Server-Client mit Sockets. Ich werde erklären, was es zu tun hat und dann den Fehler.Server vergibt keinen Thread für jeden neuen Client (Sockets)

Anwendung hat einen Server, der auf Kunden wartet. Es unterstützt maximal 6 Clients gleichzeitig. Für jeden Client-Server starten Sie einen Thread in DETASH_STATE und dann kommt er zurück und hört zu.

Ein Client übermittelt den Kontext einer Datei an den Server. (I wählte Zeile für Zeile senden)

Der Server wird der Inhalt durch einen Client gesendet empfangen und in einer Datei zu speichern, mit einem eindeutigen Namen wie: __ft_ „Any zufällige Zeichenfolge“ .txt

Ich hoffe, Alles ist bis jetzt klar.

Der Fehler: Nun, wenn ich den Client starten lassen sagen 20 Mal. Auf Serverseite habe ich keine 20 Dateien. Manchmal habe ich 10, manchmal 12,5,7 (unvorhersehbar). Es schreibt den von 3 oder 4 oder 5 Clients gesendeten Inhalt in einer einzigen Datei (hier muss ich 3-4-5 Dateien haben). Ich verstehe nicht, wo der Käfer ist oder was ich falsch gemacht habe. Wenn Sie zusätzliche Informationen benötigen, sagen Sie es mir bitte.

Dies ist der Server-Code (ein Teil davon):

/**********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; 
} 

Und dies ist der Client-Code (ich glaube nicht, hier ist das Problem):

#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; 
} 
+1

Sie überprüfen nicht, ob Ihre Funktion 'create_random_name' den gleichen Dateinamen mehr als einmal erzeugt. – Nadir

+0

ist es möglich, den gleichen Namen zu generieren und deshalb schreibt es in der gleichen Datei? –

+0

Es ist möglich (Die Chancen dafür sind gering, aber sie sind da). Ändern Sie es so, dass es nie einen Namen für eine Datei zurückgibt, die bereits existiert – Nadir

Antwort

1

Dies ist ein Fehler:

(void*) &client_socket 

Erstens, keine Notwendigkeit zu void* gegossen. Zweitens sieht es so aus, als ob eine lokale Variable ist, deren Adresse Sie als Kontext an den Thread übergeben. Im Startthread überschreiben Sie dann seinen Wert mit der nächsten Iteration.

+0

Hallo danke für deine Zeit. Was soll ich mit client_socket tun, wenn Sie sagen, dass es sich um eine lokale Variable handelt? –

+0

Erstens würde es wirklich helfen, wenn Sie ein minimales Beispiel geben würden, wie die Site-Richtlinien tatsächlich erfordern. Wie man Kontextinformationen an einen Thread richtig weitergibt, sollte in jedem Thread-Tutorial erläutert oder gezeigt werden. Um es zu beheben, können Sie die Kontextinformationen entweder dynamisch zuweisen oder den Ganzzahlwert als ungültigen Zeigerwert übergeben. –

Verwandte Themen