2015-04-07 19 views
0

我目前正在編寫一個C服務器,目標是使用pthreads來處理客戶端連接,所有工作都很好,直到我引入pthread。我在pthread上釋放了一個客戶端,並創建並運行正常;但是,它不會再從客戶端的文件描述符中讀取()。從pthread調用時,read()不起作用C

我一直在試圖找出大概2周現在。我已經包含了服務器代碼(包括和不包括pthread)以及客戶端處理程序代碼的代碼片段。

這裏是我的主服務器循環(pthreaded):

/*Sets up and runs the server. (MAX 10 CLIENTS)*/ 
void publicServer(void) 
{ 
    //Server locals 
    int serverSocket_fd; 
    int clientSocket_fd; 
    socklen_t serverLength; 
    socklen_t clientLength; 
    struct sockaddr_in serverAddress; 
    struct sockaddr_in clientAddress; 

    //Threading locals 
    pthread_t threadPool[20]; //Pool of threads, used in a FIFO fashion. 
    int threadPointer = 0;  //Points to the location of the next available thread. 

    //Clear old sockets 
    puts("Unlinking server socket"); 
    unlink("server_socket"); 

    //Setup server socket 
    printf("Setting server socket properties..\n"); 
    serverSocket_fd     = socket(AF_INET, SOCK_STREAM, 0); 
    serverAddress.sin_family  = AF_INET; 
    serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); 
    serverAddress.sin_port   = htons(5000); 
    serverLength = sizeof(serverAddress); 

    //Bind the socket 
    printf("Binding socket\n"); 
    bind(serverSocket_fd, (struct sockaddr*)&serverAddress, serverLength); 

    //Create listener 
    listen(serverSocket_fd, 20); 

    //Main server loop 
    printf("Entering main loop\n"); 
    while (1) 
    { 
     clientLength = sizeof(clientAddress); 

     //Accept connection 
     printf("Blocking for connection\n"); 
     clientSocket_fd = accept(serverSocket_fd, (struct sockaddr*)&clientAddress, &clientLength); 

     //Handle Client 
     pthread_create(&threadPool[0], NULL, clientHandler, clientSocket_fd); 

     //Increment thread pointer 
     threadPointer++; 
     if (threadPointer == 20) 
     { 
      threadPointer = 0; 
     } 

     //End client 
     close(clientSocket_fd); 
    } 
} 

這裏是沒有並行線程的服務器代碼(正常工作。):

/*Sets up and runs the server. (MAX 10 CLIENTS)*/ 
void publicServer(void) 
{ 
    //Server locals 
    int serverSocket_fd; 
    int clientSocket_fd; 
    socklen_t serverLength; 
    socklen_t clientLength; 
    struct sockaddr_in serverAddress; 
    struct sockaddr_in clientAddress; 

    //Clear old sockets 
    puts("Unlinking server socket"); 
    unlink("server_socket"); 

    //Setup server socket 
    printf("Setting server socket properties..\n"); 
    serverSocket_fd     = socket(AF_INET, SOCK_STREAM, 0); 
    serverAddress.sin_family  = AF_INET; 
    serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); 
    serverAddress.sin_port   = htons(5000); 
    serverLength = sizeof(serverAddress); 

    //Bind the socket 
    printf("Binding socket\n"); 
    bind(serverSocket_fd, (struct sockaddr*)&serverAddress, serverLength); 

    //Create listener 
    listen(serverSocket_fd, 20); 

    //Main server loop 
    printf("Entering main loop\n"); 
    while (1) 
    { 
     clientLength = sizeof(clientAddress); 

     //Accept connection 
     printf("Blocking for connection\n"); 
     clientSocket_fd = accept(serverSocket_fd, (struct sockaddr*)&clientAddress, &clientLength); 

     //Handle Client 
     clientHandler(clientSocket_fd); 

     //End client 
     close(clientSocket_fd); 
    } 
} 

下面是客戶端處理程序代碼:

/* 
* Handles the client's request. 
* <int : client_fd> Client's file descriptor. 
*/ 
void *clientHandler(int client_fd) 
{ 
    char request = ' '; 

    puts("Waiting for request"); 
    read(client_fd, &request, 1); 

    //Determine what to do for user 
    if (request == '1')     //Output current temp and pressure 
    { 
     outputCurrentTemperaturePressure(client_fd); 
    } 
    else if (request == '2')   //Begin regular sampling of temp and pressure 
    { 
     startSampling(); 
    } 
    else if (request == '3')   //Stop regular sampling of temp and pressure 
    { 
     stopSampling(); 
    } 
    else if (request == '4')   //Clear the EEPROM 
    { 
     eraseEEPROM(); 
    } 
    else if (request == '5')   //Retrieve all stored temperature and pressure values 
    { 
     outputSavedTempPressValues(client_fd); 
    } 
    else if (request == '6')   //Retrieve a certain number of temperature and pressure values 
    { 
     outputLastNTempPressValues(client_fd); 
    } 
    else if (request == '7')   //Output current noise level 
    { 
     outputCurrentNoiseLevel(client_fd); 
    } 

    close(client_fd); 
    pthread_exit(1); 
} 

問題是當我嘗試從客戶端讀取時,在clientHandler方法中的第6行。當在pthread上運行時,它始終讀取0。但是,如果在沒有pthread的情況下運行,它會讀取正確的值。我希望有人能夠幫助解決這個問題,因爲這真的讓我感到困惑。

由於提前, 安迪

回答

0

正好接近客戶端線程socket_fd,但不是主要功能

while (1) 
{ 
    clientLength = sizeof(clientAddress); 

    //Accept connection 
    printf("Blocking for connection\n"); 
    clientSocket_fd = accept(serverSocket_fd, (struct sockaddr*)&clientAddress, &clientLength); 

    //Handle Client 
    pthread_create(&threadPool[0], NULL, clientHandler, clientSocket_fd); 

    //Increment thread pointer 
    threadPointer++; 
    if (threadPointer == 20) 
    { 
     threadPointer = 0; 
    } 

    //End client 
    /* remove close(clientSocket_fd) from here */ 
} 

當您運行,而新的線程,循環仍然關閉cliend文件描述符,那就是爲什麼read()不工作

+0

修復了read()的問題,所以謝謝你!但是現在我被大量的等待的pthreads卡住了。我必須找出一些辦法來阻止服務器環路。 – Sciprios

+0

okey :)查看最新帖子 –

+0

啊謝謝!你已經度過了我的一天! :) – Sciprios

0
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, 
         void *(*start_routine) (void *), void *arg); 


pthread_create(&threadPool[0], NULL, clientHandler, (void*)&clientSocket_fd); 

void *clientHandler(void *args) { 
int client_fd = *((int*) args); 
相關問題