Example #1
0
int				ser_prend(t_env *env, t_fd *fd, char *cmd)
{
	t_square	*sq;
	int			quantity_sq;
	t_resource	res;

	sq = get_square(env, fd->trantor.pos_x, fd->trantor.pos_y);
	res = str_to_resource(cmd + 6);
	quantity_sq = nb_res_in_inventory(&sq->content, res);
	if (quantity_sq < 1)
	{
		send_cmd_to_client(fd, MSG_KO);
		return (-1);
	}
	add_resource(&fd->trantor.inventory, res);
	del_resource(&sq->content, res);
	send_infos(env, fd, res);
	return (0);
}
Example #2
0
int main( int argc, char* argv[] )
{
    if( argc <= 2 )
    {
        printf( "usage: %s ip_address port_number\n", basename( argv[0] ) );
        return 1;
    }
    const char* ip = argv[1];
    int port = atoi( argv[2] );

    int ret = 0;
    struct sockaddr_in address;
    bzero( &address, sizeof( address ) );
    address.sin_family = AF_INET;
    inet_pton( AF_INET, ip, &address.sin_addr );
    address.sin_port = htons( port );

    listenfd = socket( PF_INET, SOCK_STREAM, 0 );
    assert( listenfd >= 0 );

    ret = bind( listenfd, ( struct sockaddr* )&address, sizeof( address ) );
    assert( ret != -1 );

    ret = listen( listenfd, 5 );
    assert( ret != -1 );

    for( int i = 0; i < PROCESS_COUNT; ++i )
    {
        ret = socketpair( PF_UNIX, SOCK_STREAM, 0, sub_process[i].pipefd );
        assert( ret != -1 );
        sub_process[i].pid = fork();
        if( sub_process[i].pid < 0 )
        {
            continue;
        }
        else if( sub_process[i].pid > 0 )
        {
            close( sub_process[i].pipefd[1] );
            setnonblocking( sub_process[i].pipefd[0] );
            continue;
        }
        else
        {
            close( sub_process[i].pipefd[0] );
            setnonblocking( sub_process[i].pipefd[1] );
            run_child( i );
            exit( 0 );
        }
    }

    epoll_event events[ MAX_EVENT_NUMBER ];
    epollfd = epoll_create( 5 );
    assert( epollfd != -1 );
    addfd( epollfd, listenfd );

    ret = socketpair( PF_UNIX, SOCK_STREAM, 0, sig_pipefd );
    assert( ret != -1 );
    setnonblocking( sig_pipefd[1] );
    addfd( epollfd, sig_pipefd[0] );

    addsig( SIGCHLD, sig_handler );
    addsig( SIGTERM, sig_handler );
    addsig( SIGINT, sig_handler );
    addsig( SIGPIPE, SIG_IGN );
    bool stop_server = false;
    int sub_process_counter = 0;

    while( !stop_server )
    {
        int number = epoll_wait( epollfd, events, MAX_EVENT_NUMBER, -1 );
        if ( ( number < 0 ) && ( errno != EINTR ) )
        {
            printf( "epoll failure\n" );
            break;
        }

        for ( int i = 0; i < number; i++ )
        {
            int sockfd = events[i].data.fd;
            if( sockfd == listenfd )
            {
                int new_conn = 1;
                send( sub_process[sub_process_counter++].pipefd[0], ( char* )&new_conn, sizeof( new_conn ), 0 );
                printf( "send request to child %d\n", sub_process_counter-1 );
                sub_process_counter %= PROCESS_COUNT;
            }
            else if( ( sockfd == sig_pipefd[0] ) && ( events[i].events & EPOLLIN ) )
            {
                int sig;
                char signals[1024];
                ret = recv( sig_pipefd[0], signals, sizeof( signals ), 0 );
                if( ret == -1 )
                {
                    continue;
                }
                else if( ret == 0 )
                {
                    continue;
                }
                else
                {
                    for( int i = 0; i < ret; ++i )
                    {
                        switch( signals[i] )
                        {
                            case SIGCHLD:
                            {
	                        pid_t pid;
	                        int stat;
	                        while ( ( pid = waitpid( -1, &stat, WNOHANG ) ) > 0 )
                                {
                                    for( int i = 0; i < PROCESS_COUNT; ++i )
                                    {
                                        if( sub_process[i].pid == pid )
                                        {
                                            close( sub_process[i].pipefd[0] );
                                            sub_process[i].pid = -1;
                                        }
                                    }
                                }
                                stop_server = true;
                                for( int i = 0; i < PROCESS_COUNT; ++i )
                                {
                                    if( sub_process[i].pid != -1 )
                                    {
                                        stop_server = false;
                                    }
                                }
                                break;
                            }
                            case SIGTERM:
                            case SIGINT:
                            {
                                printf( "kill all the clild now\n" );
                                for( int i = 0; i < PROCESS_COUNT; ++i )
                                {
                                    int pid = sub_process[i].pid;
                                    kill( pid, SIGTERM );
                                }
                                break;
                            }
                            default:
                            {
                                break;
                            }
                        }
                    }
                }
            }
            else 
            {
                continue;
            }
        }
    }

    del_resource();
    return 0;
}
int main(int argc ,char* argv[])
{
	if(argc <= 2)
	{
		printf("usage : %s ip_address port_number \n",argv[0]);
		return 1;
	}
	const char* ip = argv[1];
	int port = atoi(argv[2]);

	int ret =0;

	struct sockaddr_in address;
	bzero(&address,sizeof(address));
	address.sin_family = AF_INET;
	inet_pton(AF_INET,ip,&address.sin_addr);
	address.sin_port = htons(port);

	listenfd = socket(PF_INET,SOCK_STREAM,0);

	assert(listenfd >= 0);

	ret = bind(listenfd,(struct sockaddr*) &address,sizeof(address));
	assert(ret != -1);

	ret = listen(listenfd,5);

	assert(ret != -1);

	user_count = 0;
	users =  (client_data *) malloc(sizeof(client_data)*(USER_LIMIT+1));
	sub_process = (int *)malloc(sizeof(int)*(PROCESS_LIMIT+1));

	int i = 0;
	for(; i<PROCESS_LIMIT;++i)
	{
		sub_process[i] = -1;
	}


	struct epoll_event events[MAX_EVENT_NUMBER];
	epollfd = epoll_create(5);
	assert(epollfd != -1);
	addfd(epollfd,listenfd);

	ret = socketpair(PF_UNIX,SOCK_STREAM,0,sig_pipefd);

	assert(ret != -1);

	setnonblocking(sig_pipefd[1]);
	addfd(epollfd,sig_pipefd[0]);

	addsig(SIGCHLD,sig_handler,true);
	addsig(SIGTERM,sig_handler,true);
	addsig(SIGINT,sig_handler,true);
	addsig(SIGPIPE,SIG_IGN,true);
	bool stop_server = false;
	bool terminate = false;

	shmfd = shm_open(shm_name,O_CREAT|O_RDWR,0666);
	assert(shmfd != -1);
	ret = ftruncate(shmfd,USER_LIMIT*BUFFER_SIZE);
	assert(ret != -1);

	share_mem = (char*) mmap(NULL,USER_LIMIT*BUFFER_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,shmfd,0);

	assert(share_mem != MAP_FAILED);
	close(shmfd);

	while(!stop_server)
	{
		int number = epoll_wait(epollfd,events,MAX_EVENT_NUMBER,-1);
		if((number <0) && (errno != EINTR))
		{
			printf("epoll failure\n");
			break;
		}
		int i = 0;
		for(;i<number;i++)
		{
			int sockfd = events[i].data.fd;

			// 处理客户端链接请求
			if(sockfd == listenfd)
			{
				struct sockaddr_in client_address;
				socklen_t client_addrlength = sizeof(client_address);
				int connfd = accept(listenfd,(struct sockaddr*)&client_address,&client_addrlength);

				if(connfd < 0)
				{
					printf("errno is :%d\n",errno);
					continue;
				}

				if(user_count >= USER_LIMIT)
				{
					const char* info ="too many users\n";
					printf("%s",info);
					send(connfd,info,strlen(info),0);
					close(connfd);
					continue;
				}

				users[user_count].address = client_address;
				users[user_count].connfd = connfd;

				ret = socketpair(PF_UNIX,SOCK_STREAM,0,users[user_count].pipefd);

				assert(ret != -1);
				pid_t pid = fork();

				if(pid <0)
				{
					close(connfd);
					continue;

				}
				else if(pid == 0)
				{
					close(epollfd);
					close(listenfd);
					close(users[user_count].pipefd[0]);
					close(sig_pipefd[0]);
					close(sig_pipefd[1]);
					run_child(user_count,users,share_mem);
					munmap((void*)share_mem,USER_LIMIT*BUFFER_SIZE);
					exit(0);
				}
				else {
					close(connfd);
					close(users[user_count].pipefd[1]);
					addfd(epollfd,users[user_count].pipefd[0]);
					users[user_count].pid = pid;
					sub_process[pid]= user_count;
					user_count ++;
				}

			}

			// 处理信号事件
			else if( sockfd == sig_pipefd[0] && (events[i].events & EPOLLIN))
			{
				int sig;
				char signals[1024];
				ret = recv(sig_pipefd[0],signals,sizeof(signals),0);

				if( ret == -1)
				{
					continue;
				}
				else if ( ret == 0)
				{
					continue;
				}
				else
				{
					int i=0;
					for ( ;i< ret; ++i)
					{
						switch(signals[i])
						{
							case SIGCHLD:
							{
								pid_t pid;
								int stat;

								while(( pid = waitpid(-1,&stat,WNOHANG)) > 0)
								{
									/* 用子进程pid获取关闭的客户端的编号
									 *
									 */
									int del_user = sub_process[pid];

									sub_process[pid] = -1;
									if((del_user < 0) || (del_user> USER_LIMIT))
									{
										continue;
									}
									//清除此客户链接使用的相关数据,更新user和sub_process数组

									epoll_ctl(epollfd,EPOLL_CTL_DEL,users[del_user].pipefd[0],0);
									close(users[del_user].pipefd[0]);
									users[del_user]= users[--user_count];
									sub_process[users[del_user].pid] = del_user;
								}

								if(terminate && user_count == 0)
								{
									stop_server = true;
								}

								break;
							}
							case SIGTERM:
							case SIGINT:
							{
								printf("kill all the child now \n");
								if(user_count ==0)
								{
									stop_server = true;
									break;

								}
								int i=0;
								for(;i<user_count;++i)
								{
									int pid = users[i].pid;
									kill(pid,SIGTERM);

								}

								terminate = true;
								break;
							}
							default:
							{
								break;
							}

						}

					}

				}

			}
			else if(events[i].events & EPOLLIN)
			{
				int child = 0;

				ret = recv(sockfd,(char*)&child,sizeof(child),0);

				printf("read data from child accross pipe\n");
				if(ret == -1)
				{
					continue;
				}
				else if (ret ==0)
				{
					continue;
				}
				else
				{
					int j =0;
					for( ;j<user_count;++j)
					{
						if(users[j].pipefd[0] != sockfd)
						{
							printf("send data to child accross pipe\n");
							send(users[j].pipefd[0],(char*)&child,sizeof(child),0);
						}
					}
				}
			}



		}

	}

	del_resource();
	return 0;
}