2013-10-24 2 views
0

메신저로 멀티 쓰레드 서버를 작성했습니다. 어떻게 디버깅하려했는지는 모르겠지만 어떤 이유로 pthread_create()에 의해 호출 된 클라이언트 스레드에 실제로 들어 가지 않습니다. pthread_create()가 실패한 이유는 무엇입니까?C - 서버 클라이언트 멀티 스레드 pthread_create가 실패했습니다

또한 구조체를 클라이언트에 보내고 클라이언트가 서버와 클라이언트 사이의 주 통신으로 구조체를 서버로 다시 보내는 것이 좋은지 궁금합니다. 또는 send() 및 recv()를 구현하는 것이 더 좋은 방법일까요?

int main(int argc, char* argv[]) 
{ 
    int fdServer; 
    int accept_fd; 
    int optVal = 1; 
    struct sockaddr_in fromAddr; 
    struct sockaddr_in serverAddr; 
    struct pollfd* pServerPollFd; 
    pthread_t threadId; 
    socklen_t fromAddrSize; 

    /* 
    * Check user input and assign values 
    */ 
    if(argc != 4) 
     errorServer(WRONG_CLI); 
    char* greeting = calloc(100,sizeof(char*)); 
    char* file_name = calloc(100,sizeof(char*)); 
    greeting = argv[2]; 
    file_name = argv[3]; 

    /* 
    * Check pthread_key_create != 0 -> ERROR 
    */ 
    if(pthread_key_create(&threadSpecificKey, dataDestructor)) 
     errorServer(SYSTEM_ERROR); 
    int port_num = atoi(argv[1]); 
    if(!((port_num <= 65535)&&(1<=port_num))) 
     errorServer(INVALID_PORT); 

    /* 
    * Set up the server socket 
    */ 
    fdServer = socket(AF_INET, SOCK_STREAM, 0); 
    if(fdServer < 0) 
     errorServer(SYSTEM_ERROR); 
    if(setsockopt(fdServer, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(int)) < 0) 
     errorServer(SYSTEM_ERROR); 
    serverAddr.sin_family = AF_INET; 
    serverAddr.sin_port = htons(port_num); 
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    if(bind(fdServer, (struct sockaddr*)&serverAddr, sizeof(struct sockaddr_in)) < 0) 
     errorServer(PORT_ERROR); 

    /* 
    * Setup poll pool 
    */ 
    pMessageBuffer = fifo_buffer_create(-1); 
    poll_pool* pPool = poll_pool_create(MAX_CONNECTIONS + 1); 
    pServerPollFd = poll_pool_allocate(pPool, fdServer); 
    pServerPollFd->events |= POLLIN; 
    int flags = fcntl(fdServer, F_GETFL);// Get the file access mode and the file status flags; 
    if(fcntl(fdServer, F_SETFL, flags | O_NONBLOCK) == -1)// Set the file descriptor flags to the value specified by 3rd arg. 
      errorServer(SYSTEM_ERROR); 
    if(listen(fdServer, 4) != 0)//Allow only 4 connections to the server 
      errorServer(SYSTEM_ERROR); 




    while(1) { 

      fromAddrSize = sizeof(struct sockaddr_in); 
     /* Block, waiting for a connection request to come in and accept it. 
     * fromAddr structure will get populated with the address of the client 
     */ 
      while((accept_fd = accept(fdServer, (struct sockaddr*)&fromAddr, &fromAddrSize)) != -1){ 
       printf("Someone connected \n"); 

      client_connection *pClientConnection = client_connection_create(accept_fd); 
      client_details *pClientDetails = client_details_create(); 
      client_session *pClientSession = client_session_create(pClientConnection,pClientDetails); 

      pthread_mutex_lock(&game_state_mutex); 
      //SEARCH THE LINKEDLIST FOR THE GAME NAME - IF FALSE CREATE NEW LINKED ELEMENT 
      C_lst requestedGame; 
      clst_init(&requestedGame,NULL); 
      clst_insert_next(&requestedGame,NULL,pClientSession); 

      pthread_mutex_unlock(&game_state_mutex); 
      write(accept_fd, greeting, strlen(greeting)); 



     /* Start a thread to deal with client communication - pass the 
     * connected file descriptor as the last argument. 
     */ 
      pthread_create(&threadId, NULL, client_thread, (void*)pClientSession); 
      pthread_detach(threadId); 
      } 

    } 
    free(greeting); 
    free(file_name); 
    return 0; 
} 

그리고 이것은 당신이는 pthread_create 반환 값을 확인하지 및 오류 메시지가 해당 인쇄되지 왜 client_thread

void * client_thread(void* arg) 
    { 
    ssize_t numBytesRead; 
    char buffer[MAXBUFFER]; 
    client_session* pClientSession = (client_session*)arg; 

    if(pthread_setspecific(threadSpecificKey, pClientSession)) 
     errorServer(SYSTEM_ERROR); 
/* below read fails because of the nonblocking fdServer from fnctl*/ 
while((numBytesRead = read(fd,buffer,MAXBUFFER))>0){ 
    //loop code here 
    } 
+0

읽지 않은 것이 있으면 EAGAIN으로 비 차단 읽기가 실패합니다. 그런 상황을 제대로 처리해야합니다. – zoska

답변

1

의 시작인가?

s = pthread_create(...); 
if (s != 0) { 
    errno = s; 
    perror("pthread_create"); 
    exit(EXIT_FAILURE); 
} 

자료 :는 pthread_create (3)

UPD. 또한 소켓 설정을 위해 손으로 직접하는 대신 getaddrinfo (3)을 시도 할 수 있습니다 : http://www.beej.us/guide/bgnet/output/html/multipage/syscalls.html#getaddrinfo

UPD 2. '구조체 전송'이란 무엇을 의미합니까?

+0

Ive에 코드를 추가했지만 아무것도 표시하지 않습니까? –

+0

나는 그것을 인쇄했고 그것은 제로 다. 그래서 그것은 그것을 잘 실행하고있다. 이것은 정말로 이상하다! –

+0

@MarkNicolle, 이제는 문제가 pthread_create가 아니라는 것을 알고 있습니다. 다른 시스템 기능을 확인하는 것은 어떨까요? – JIghtuse

관련 문제