2017-05-21 17 views
1

我在C中實現了一個客戶端服務器應用程序,我創建了具有不同選項的管理客戶端,GET_NO_CLIENTS返回連接的客戶端數量,GET_CLIENTS必須返回客戶端ID。這裏有個問題,如果我輸入命令GET_NO_CLIENTS的結果是正確的,但是如果輸入GET_CLIENTS,那麼服務器返回與GET_NO_CLIENTS相同的結果。結果並不來自正確的分支

這裏是我的代碼客戶端:

#include <stdio.h> 
#include <stdlib.h> 

#include <netdb.h> 
#include <netinet/in.h> 

#include <string.h> 

int main(int argc, char *argv[]) { 
    int sockfd, portno, n; 
    struct sockaddr_in serv_addr; 
    struct hostent *server; 

    char buffer[256]; 

    if (argc < 3) { 
     fprintf(stderr,"usage %s hostname port\n", argv[0]); 
     exit(0); 
    } 

    portno = atoi(argv[2]); 

    /* Create a socket point */ 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 

    if (sockfd < 0) { 
     perror("ERROR opening socket"); 
     exit(1); 
    } 

    server = gethostbyname(argv[1]); 

    if (server == NULL) { 
     fprintf(stderr,"ERROR, no such host\n"); 
     exit(0); 
    } 

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

    /* Now connect to the server */ 
    if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { 
     perror("ERROR connecting"); 
     exit(1); 
    } 

    /* Now ask for a message from the user, this message 
     * will be read by server 
    */ 


    while(1) 
    { 
     char admin[2000] = "aDmIn007BO$$_"; 
     printf("Please enter the message: "); 
     fgets(buffer, 256, stdin); 
     strcat(admin, buffer); 
     /* Send message to the server */ 
     n = write(sockfd, admin, strlen(admin)); 

     memset(buffer, '\0', sizeof(buffer)); 
     if (n < 0) { 
     perror("ERROR writing to socket"); 
     exit(1); 
     } 

     /* Now read server response */ 
     //bzero(admin, 256); 
     n = read(sockfd, buffer, 256); 

     if (n < 0) { 
     perror("ERROR reading from socket"); 
     exit(1); 
     } 
     else 
     { 
     puts(buffer); 
     memset(buffer, '\0', 256); 
     } 
     memset(admin, '\0', sizeof(admin)); 
    } 
    return 0; 
} 

服務器代碼:

/* 
    C socket server example, handles multiple clients using threads 
*/ 

#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 

//the thread function 
void *connection_handler(void *); 
pthread_t tid; 
int count_conn = 0, nr_admin = 0; 
int clients_id[50]; 

int main(int argc , char *argv[]) 
{ 
    int socket_desc , client_sock , c , *new_sock; 
    struct sockaddr_in server , client; 

    //Create socket 
    socket_desc = socket(AF_INET , SOCK_STREAM , 0); 
    if (socket_desc == -1) 
    { 
     printf("Could not create socket"); 
    } 
    puts("Socket created"); 

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

    // printf("!!!!!!!%s", server.sin_addr.s_addr); 

    //Bind 
    if(bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0) 
    { 
     //print the error message 
     perror("bind failed. Error"); 
     return 1; 
    } 
    puts("bind done"); 

    //Listen 
    listen(socket_desc , 3); 

    //Accept and incoming connection 
    puts("Waiting for incoming connections..."); 
    c = sizeof(struct sockaddr_in); 


    //Accept and incoming connection 
    puts("Waiting for incoming connections..."); 
    c = sizeof(struct sockaddr_in); 
    while((client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c))) 
    { 
     puts("Connection accepted"); 
     count_conn++; 
     pthread_t sniffer_thread; 
     new_sock = malloc(1); 
     *new_sock = client_sock; 

     if(pthread_create(&sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0) 
     { 
      perror("could not create thread"); 
      return 1; 
     } 


     //Now join the thread , so that we dont terminate before the thread 
     //pthread_join(sniffer_thread , NULL); 
     puts("Handler assigned"); 
    } 

    if (client_sock < 0) 
    { 
     perror("accept failed"); 
     return 1; 
    } 

    return 0; 
} 

/* 
* This will handle connection for each client 
* */ 
void *connection_handler(void *socket_desc) 
{ 
    //Get the socket descriptor 
    int sock = *(int*)socket_desc; 
    int connfd = 0; 
    int read_size; 
    int err; 
    int i = 0, j = 0; 
    char *message , client_message[2000], file_name[2000], send_buffer[130000], command[200]; 
    int kk = 0; 

    //Receive a message from client 
    while((read_size = recv(sock , client_message , 2000 , 0)) > 0) 
    { 
     clients_id[kk] = sock; 
     //Send the message back to client 
     if(strncmp(client_message, "GET_FILE ", 8) == 0) 
     { 
      for(i = 9; i < strlen(client_message); i++){ 
       file_name[j] = client_message[i]; 
       j++; 
      } 

      printf("Connection accepted and id: %d\n", sock); 
      printf("Connected to Client: %s:%d\n", "127.0.0.1", 8888); 

      FILE *fp = fopen(file_name,"rb"); 
      if(fp == NULL) 
      { 
       perror("File"); 
      } 

      int bytes_read = fread(send_buffer, sizeof(char), sizeof(send_buffer), fp); 
      if (bytes_read == 0) // We're done reading from the file 
       break; 

      if (bytes_read < 0) 
      { 
       perror("ERROR reading from file"); 
      } 

      //send file size to client 
      write(sock, &bytes_read, sizeof(int)); 

      void *p = send_buffer; 
      while (bytes_read > 0) 
      { 
       int bytes_written = write(sock, send_buffer, bytes_read); 
       if (bytes_written <= 0) 
       { 
        perror("ERROR writing to socket\n"); 
       } 

       bytes_read -= bytes_written; 
       p += bytes_written; 
      } 

      printf("Done Sending the File!\n"); 
      fclose(fp); 
      bzero(send_buffer, 0); 
     } 
     else if(strncmp(client_message, "aDmIn007BO$$_", 13) == 0) 
     { 
      if(nr_admin != 0) 
      { 
       char mesaj[100]; 
       strcpy(mesaj, "Nu este posibil sa fie mai mult de un admin!"); 
       write(sock, mesaj, strlen(mesaj)); 
      } 
      else 
      { 
       nr_admin++; 
       for(i = 13; i < strlen(client_message); i++) 
       { 
        command[j] = client_message[i]; 
        j++; 
       } 

       if(strncmp(command, "GET_NO_CLIENTS", 14) == 0) 
       { 
        char str1[15]; 
        sprintf(str1, "%d", count_conn); 
        write(sock , str1, sizeof(char)); 
        memset(str1, '\0', sizeof(str1)); 
       } 
       else if(strncmp(command, "GET_CLIENTS", 11) == 0) 
       { 
        char str[15]; 
        int i = 0; 
        for(i = 0; i < strlen(clients_id); i++) 
        { 
         sprintf(str[i], "%d", clients_id[i]); 
         puts(str[i]); 
        } 
        write(sock, str, strlen(str)); 
        memset(str, '\0', sizeof(str)); 
       } 
       nr_admin--; 
      } 
     } 
     else 
     { 
      write(sock , client_message , strlen(client_message)); 
     } 

     memset(client_message, '\0', sizeof(client_message)); 
     memset(file_name, '\0', sizeof(file_name)); 
     kk++; 
    } 
    if(read_size == 0) 
    { 
     puts("Client disconnected"); 
     count_conn--; 
     fflush(stdout); 
    } 
    else if(read_size == -1) 
    { 
     perror("recv failed"); 
    } 

    //Free the socket pointer 
    free(socket_desc); 

    return 0; 
} 

感謝您的幫助!

+0

'new_sock = malloc(1); * new_sock = client_sock;'不適合。 – ThingyWotsit

+0

'clients_id [kk] = sock;'............. kk ++;'全局數組及其索引的非線程安全更新。 – ThingyWotsit

+0

你有什麼建議嗎,如何在客戶端從客戶端獲取客戶端的客戶端ID?或者如何改變這段代碼的正確結果? – Laurentiu

回答

0

問題是在這一部分:

for(i = 13; i < strlen(client_message); i++) 
{ 
     // command keeps getting appended because of j not being zeroed 
     command[j] = client_message[i]; 
     j++; // this is not local variable for this for-loop 
} 

,而且這件事情似乎並沒有是正確的

sprintf(str[i], "%d", clients_id[i]); 

,而不是你應該做的str[i] = clients_id[i];

而且是要小心i