메신저로 멀티 쓰레드 서버를 작성했습니다. 어떻게 디버깅하려했는지는 모르겠지만 어떤 이유로 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
}
읽지 않은 것이 있으면 EAGAIN으로 비 차단 읽기가 실패합니다. 그런 상황을 제대로 처리해야합니다. – zoska