示例#1
0
int main()
{
    char neterr[ANET_ERR_LEN];
    struct epoll_event ev; 

    int listenfd;

    if(!db.Open("mydb")){
        cerr<<"db open failed:"<<endl;
        return 0;
    }

    signal(SIGPIPE, SIG_IGN);	//ignore sigpipe to prevent server shut down

    thread_pool.Run();

    if((listenfd = anetTcpServer(neterr, 9999, NULL)) == ANET_ERR){
        fprintf(stderr, "%s\n", neterr);
        exit(1);
    }

    anetNonBlock(neterr, listenfd); 

    if((epfd = epoll_create(MAX_CLIENTS)) < 0){
        perror("epoll_create");
        exit(1);
    }

    ev.events = EPOLLIN; 
    ev.data.fd =listenfd; 
    if(epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev)<0){
        perror("epoll_ctl");
        exit(1);
    } 

    for(;;){ 

        int nfds = epoll_wait(epfd, events, MAX_CLIENTS, -1);  
        for(int i = 0; i < nfds; ++i) { 

            int fd = events[i].data.fd;

            if(fd  == listenfd) { 
                struct sockaddr_in	cliaddr;
                socklen_t addrlen = sizeof(cliaddr);
                int connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &addrlen); 
                if(connfd < 0){ 
                    if(errno == ECONNABORTED)	//connection aborted, ignore it
                        continue; 
                    else if(errno == EAGAIN)	//no connections are ready to be accepted
                        continue; 
                    else{	//error happened in accept, report it
                        perror("accept"); 
                        continue;
                    }
                } 

                fprintf(stderr, "a new connfd: %d\n", connfd);  
                anetNonBlock(neterr, connfd); 

                ev.events = EPOLLIN; 
                ev.data.fd = connfd; 
                if (epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev) < 0) { 
                    perror("epoll_ctl");
                    return -1; 
                } 
                clients[connfd].fd = connfd;
                nclients++;
            } 
            else if(events[i].events & EPOLLIN)  
            {  
                int n;
                char* rbuf = clients[fd].readbuf;
                while ((n = read(fd, rbuf+clients[fd].rpos, MAX_BUFLEN-clients[fd].rpos)) > 0)
                    clients[fd].rpos += n;

                if (n == 0) {  //client has been closed
                    fprintf(stderr, "client has been closed, so server also close it, fd=%d\n", fd);  
                    close(fd);  
                    nclients--;
                }
                if (n<0 && errno != EAGAIN) {
                    perror("read");
                    close(fd);  
                    nclients--;
                }
                int res = handle_read_event(&clients[fd]);
                if(res<0){ //error happened
                    fprintf(stderr, "bad command, res=%d\n", res);  
                    close(fd);  
                    nclients--;
                }else if(res>0){	//the command has been hand over to a background thread, nothing to do here
                }else{ //res == 0, needs more data, continue reading
                }
            }
            else if(events[i].events & EPOLLOUT)  
            {     
                char* wbuf = clients[fd].writebuf;
                int wend = clients[fd].wend;
                int n;
                while (wend>clients[fd].wpos && 
                        (n = write(fd, wbuf+clients[fd].wpos, wend-clients[fd].wpos)) > 0)
                    clients[fd].wpos += n;

                if (n<0 && errno != EAGAIN) {
                    perror("write");
                    close(fd);  
                    nclients--;
                }

                if(wend == clients[fd].wpos){ //write finished
                    //no need to rest for next write cause read event handler will do it
                    //register as read event
                    clients[fd].reset_for_next_read();	//reset for read
                    ev.data.fd=fd;  
                    ev.events=EPOLLIN;  
                    epoll_ctl(epfd,EPOLL_CTL_MOD,fd,&ev);  
                }
            }  
            else{ 
                //impossible!
            }
        }
    }

    return 0;
}
示例#2
0
int main(int argc, char* argv[])
{
	const char* dbname;
	const char* verifykey = NULL;
	union {
		unsigned char buf[64];
		uint256_t hash;
	};
	std::vector<node_t> nodes;
	std::vector<node_t>::const_iterator it;
	int idx, cnt, pos;
	int mode = MODE_ROOT;
	char *ptr;
	DB* db;

	if(argc<2) {
		fprintf(stderr, "Usage: %s <dbname> [key=verifier key] [<position>|<hash>|root|dump|gendata]\n", argv[0]);
		return 0;
	}

	dbname = argv[1];

	for(idx=2; idx<argc; ++idx) {
		if(!strncmp(argv[idx], "key=", 4)) {
			verifykey = argv[idx] + 4;
		} else if(!strcmp(argv[idx], "dump")) {
			mode = MODE_DUMP;
		} else if(!strcmp(argv[idx], "root")) {
			mode = MODE_ROOT;
		} else if(!strcmp(argv[idx], "gendata")) {
			mode = MODE_GENTESTDATA;
		} else if(sizeof(uint256_t)*2==strlen(argv[idx])) {
			if(!HexData(argv[idx], buf, sizeof(buf))) {
				fprintf(stderr, "Invalid hash value: %s\n", argv[idx]);
				return 0;
			}
			mode = MODE_HASH;
		} else if(argv[idx][0]>='0' && argv[idx][0]<='9') {
			pos = strtol(argv[idx], &ptr, 10);
			if(ptr && *ptr) {
				fprintf(stderr, "Invalid position value: %s\n", argv[idx]);
				return 0;
			}
			mode = MODE_POSITION;
		} else {
			fprintf(stderr, "Unknown option: %s\n", argv[idx]);
			return 0;
		}
	}

	if(MODE_GENTESTDATA==mode) {
		if(!GenTestData(dbname))
			fprintf(stderr, "Error generating data\n");
	}

	db = new DB(dbname, verifykey);
	if(!db->Open()) {
		fprintf(stderr, "Open DB failed\n");
		delete(db);
		return 0;
	}

	switch(mode) {
	case MODE_HASH:
		if(db->GetNodes(hash, nodes)) {
			idx = 0;
			for(idx=0,it=nodes.begin(); idx<nodes.size(); idx+=2) {
				fprintf(stdout, "%d: ", idx/2);
				if(idx+1<nodes.size()) {
					ShowHex(it->hash, sizeof(it->hash), false);
					++it;
					fprintf(stdout, " / ");
				}
				ShowHex(it->hash, sizeof(it->hash), true);
				++it;
			}
		} else
			fprintf(stderr, "Hash not found\n");

		break;
	case MODE_POSITION:
		if(db->GetNodes(pos, nodes)) {
			idx = 0;
			for(idx=0,it=nodes.begin(); idx<nodes.size(); idx+=2) {
				fprintf(stdout, "%d: ", idx/2);
				if(idx+1<nodes.size()) {
					ShowHex(it->hash, sizeof(it->hash), false);
					++it;
					fprintf(stdout, " / ");
				}
				ShowHex(it->hash, sizeof(it->hash), true);
				++it;
			}
		} else
			fprintf(stderr, "Error reading tree\n");

		break;
	case MODE_ROOT:
		if(db->GetRoot(nodes)) {
			fprintf(stdout, "Root %ld: ", nodes[2].data.value);
			ShowHex(nodes[2].hash, sizeof(nodes[2].hash), true);
			fprintf(stdout, "Hashes: ");
			ShowHex(nodes[0].hash, sizeof(nodes[0].hash), false);
			fprintf(stdout, " / ");
			ShowHex(nodes[1].hash, sizeof(nodes[1].hash), true);
		} else
			fprintf(stderr, "Error reading tree\n");

		break;
	case MODE_DUMP:
		if(!db->Dump())
			fprintf(stderr, "Error reading tree\n");
		break;
	}

	return 1;
}