예제 #1
0
파일: main.cpp 프로젝트: czfdlut/codeprj
void do_read(evutil_socket_t fd, short events, void *arg)
{
	struct fd_state *state = (struct fd_state *)arg;
	char buf[1024];
	size_t result;
	while (1) {
		// assert(state->write_event);
		result = recv(fd, buf, sizeof(buf), 0);
		if (result <= 0)
			break;
		printf("[%s][%d]buf=[%s]len=[%d]\n", __FILE__, __LINE__, buf,
			result);
	}

	memcpy(state->buffer, "reply", sizeof("reply"));
	assert(state->write_event);
	event_add(state->write_event, NULL);
	state->write_upto = state->buffer_used;

	if (result == 0) {
		free_fd_state(state);
	} else if (result < 0) {
		if (errno == EAGAIN)    // XXXX use evutil macro
			return;
		perror("recv");
		free_fd_state(state);
	}
}
예제 #2
0
void
do_read(evutil_socket_t fd, short events, void *arg)
{
    struct fd_state *state = arg;
    char buf[1024];
    int i;
    ssize_t result;
    while (1) {
        assert(state->write_event);
        result = recv(fd, buf, sizeof(buf), 0);
        if (result <= 0)
            break;

		printf("DEBUG: read a msg: %s\n", buf);

        for (i=0; i < result; ++i)  {
            if (state->buffer_used < sizeof(state->buffer))
                state->buffer[state->buffer_used++] = rot13_char(buf[i]);
            if (buf[i] == '\n') {
                assert(state->write_event);
                event_add(state->write_event, NULL);
                state->write_upto = state->buffer_used;
            }
        }
    }

    if (result == 0) {
        free_fd_state(state);
    } else if (result < 0) {
        if (errno == EAGAIN) // XXXX use evutil macro
            return;
        perror("recv");
        free_fd_state(state);
    }
}
예제 #3
0
void lh_epoll(int timeout) {
	if (rs_state == rs_stopping) {
        rs_state = rs_stopped;
        close(_listener);
        _listener = 0;
        //fixme: free states
		close(_epoll);
		_epoll = 0;
        lh_clear_callback();
        return;
    } else if (rs_state == rs_stopped) {
        return;
    }
	
	int n = epoll_wait(_epoll, _events, MAXEVENTS, timeout);
	for (int i = 0; i < n; i++){
		struct epoll_event *event = _events + i;
		if (_listener == event->data.fd) { //accept
			struct sockaddr_storage ss;
			socklen_t slen = sizeof(ss);
			int fd = accept(_listener, (struct sockaddr*)&ss, &slen);
			//static int na = 0;
			//printf("accept:%d\n", ++na);
			if (fd < 0) {
				perror("accept");
			} else {
				int err = fcntl(fd, F_SETFL, O_NONBLOCK);
				if (err){
					perror ("make_non_blocking");
					return;
				}
				struct fd_state *state = alloc_fd_state(fd);
				struct epoll_event evt;
				evt.data.ptr = state;
				evt.events = EPOLLIN;
				err = epoll_ctl (_epoll, EPOLL_CTL_ADD, fd, &evt);
				if (err)
					return;
			}
		} else {
			struct fd_state *state = (struct fd_state*)event->data.ptr;
			enum io_tatus status = s_ok;
			
			if ((event->events & EPOLLERR) ||(event->events & EPOLLHUP)) { //error
				free_fd_state(state);
			} else if (event->events & EPOLLIN) { //read
				status = do_read(state);
			} else if (event->events & EPOLLOUT) { //write
				status = do_write(state);
			}
			if (status == s_error || status == s_disconnect) {
				free_fd_state(state);
			}
		}
	}
}
예제 #4
0
void
do_read(evutil_socket_t fd, short events, void *arg)
{
    struct fd_state *state = arg;
    char buf[1024];
    int i;
    ev_ssize_t result;

    printf("do_read(): fd = %d\r\n", fd);
    while (1) {
        assert(state->write_event);
        result = recv(fd, buf, sizeof(buf), 0);
        printf("recv(): result = %d\r\n", result);
        if (result <= 0)
            break;

        for (i=0; i < result; ++i)  {
            if (state->buffer_used < sizeof(state->buffer))
                state->buffer[state->buffer_used++] = rot13_char(buf[i]);
            if (buf[i] == '\n') {
                //assert(state->write_event);
                //event_add(state->write_event, NULL);
                state->write_upto = state->buffer_used;
                buf[state->buffer_used] = '\0';
                printf("\r\n");
                printf("bufsize = %d, buf = %s\r\n", state->buffer_used, buf);
            }
        }
    }

    if (result == 0) {
        free_fd_state(state);
    } else if (result < 0) {
        //if (errno == EAGAIN) // XXXX use evutil macro
        //    return;
        int err = evutil_socket_geterror(fd);
        if (EVUTIL_ERR_RW_RETRIABLE(err)) {
            // WSAEWOULDBLOCK or WSAEINTR
            printf("event_del(state->read_event);\r\n");
            event_del(state->read_event);
            return;
        }
        else {
            perror("recv");
            free_fd_state(state);
        }
    }
}
예제 #5
0
void
do_write(evutil_socket_t fd, short events, void *arg)
{
    struct fd_state *state = arg;

    while (state->n_written < state->write_upto) {
        ssize_t result = send(fd, state->buffer + state->n_written,
                              state->write_upto - state->n_written, 0);
		printf("DEBUG: write a msg: %s\n", state->buffer);
        if (result < 0) {
            if (errno == EAGAIN) // XXX use evutil macro
                return;
            free_fd_state(state);
            return;
        }
        assert(result != 0);

        state->n_written += result;
    }

    if (state->n_written == state->buffer_used)
        state->n_written = state->write_upto = state->buffer_used = 1;

    event_del(state->write_event);
}
예제 #6
0
void do_write(evutil_socket_t fd, short events, void *arg)
{
    struct fd_state *state = arg;

    //while (state->n_written < state->write_upto)
    {
        //ssize_t result = send(fd, state->buffer + state->n_written,
        //state->write_upto - state->n_written, 0);
        char res[] = {'a','b','\0','d'};
        ssize_t result = send(fd, res/*state->buffer*/,sizeof(res) /*strlen(state->buffer)*/, 0);
        if (result < 0) {
            if (errno == EAGAIN)    // XXX use evutil macro
                return;
            free_fd_state(state);
            return;
        }
        assert(result != 0);
        state->n_written += result;
    }

    //if (state->n_written == state->buffer_used)
    {
        state->n_written = state->write_upto = state->buffer_used = 1;
    }

    event_del(state->write_event);
}
예제 #7
0
파일: main.cpp 프로젝트: czfdlut/codeprj
void do_write(evutil_socket_t fd, short events, void *arg)
{
	struct fd_state *state = (struct fd_state *)arg;

	printf("[%d]\n", __LINE__);
	//while (state->n_written < state->write_upto)
	{
		//ssize_t result = send(fd, state->buffer + state->n_written,
		//state->write_upto - state->n_written, 0);
		size_t result =
			send(fd, state->buffer, strlen(state->buffer), 0);
		if (result < 0) {
			if (errno == EAGAIN)    // XXX use evutil macro
				return;
			free_fd_state(state);
			return;
		}
		assert(result != 0);
		state->n_written += result;
	}

	//if (state->n_written == state->buffer_used)
	{
		state->n_written = state->write_upto = state->buffer_used = 1;
	}

	event_del(state->write_event);
}
예제 #8
0
void do_read(evutil_socket_t fd, short events, void *arg)
{
    printf("begin read !\n");
    struct fd_state *state = arg;
    char buf[1024];
    int i = 0;
    ssize_t result;
    bzero(buf,sizeof(buf));

    while (1) {
        // assert(state->write_event);
        result = read(fd, buf + i,1);
        if (result <= 0) break;
        i += result;
        printf("[%s][%d]buf=[%s]len=[%d]\n", __FILE__, __LINE__, buf,result);
    }

    char* el = memchr(buf, '\n',i);
    printf("end : %s\n",el);

    memcpy(state->buffer,buf,sizeof(buf));
    assert(state->write_event);
    event_add(state->write_event, NULL);
    state->write_upto = state->buffer_used;

    printf("result : %d buf total : %s\n",result,state->buffer);

    if (result == 0) {
        perror("client closed");
        free_fd_state(state);
    } else if (result < 0) {
        if (errno == EAGAIN)    // XXXX use evutil macro
            return;
        perror("recv");
        free_fd_state(state);
    }
}
예제 #9
0
파일: zeus.c 프로젝트: HardSkript/zeus
void
do_write(evutil_socket_t fd, short events, void *arg)
{
    (void) events;

    struct fd_state *state = arg;
    printf("Want to write %d blocks\n", List_count(state->outputs));

    while (List_count(state->outputs) > 0) {
        RtmpOutputMessage *this_output = List_first(state->outputs);

        printf("Block write: %u\n", this_output->data_left);

        while (this_output->data_left > 0) {
            ssize_t result = send(fd, 
                                rtmp_output_message_start_at(this_output), 
                                this_output->data_left, 
                                0);
            
            if (result < 0) {
                if (errno == EAGAIN) // XXX use evutil macro
                    return;
                free_fd_state(state);
                return;
            }
            assert(result != 0);

            this_output->data_left -= result;
            printf("\tWritten: %d\n", result);

            if (this_output->data_left == 0) {
                List_unshift(state->outputs);
                rtmp_destroy_output_message(this_output);
                break;
            }
        }
    }

    event_del(state->write_event);
}
예제 #10
0
파일: server2.c 프로젝트: vfa-taipa/sandbox
void run(void)
{
    int listener;
    struct fd_state *state[FD_SETSIZE];
    struct sockaddr_in sin;
    int i, maxfd;
    fd_set readset, writeset, exset;

    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = 0;
    sin.sin_port = htons(8081);

    for (i = 0; i < FD_SETSIZE; ++i)
        state[i] = NULL;

    listener = socket(AF_INET, SOCK_STREAM, 0);
    make_nonblocking(listener);

    if (bind(listener, (struct sockaddr*)&sin, sizeof(sin)) < 0) {
        perror("bind");
        return;
    }

    if (listen(listener, 16)<0) {
        perror("listen");
        return;
    }

    FD_ZERO(&readset);
    FD_ZERO(&writeset);
    FD_ZERO(&exset);

    while (1) {
        maxfd = listener;

        FD_ZERO(&readset);
        FD_ZERO(&writeset);
        FD_ZERO(&exset);

        FD_SET(listener, &readset);

        for (i=0; i < FD_SETSIZE; ++i) {
            if (state[i]) {
                if (i > maxfd)
                    maxfd = i;
                FD_SET(i, &readset);
                if (state[i]->writing) {
                    FD_SET(i, &writeset);
                }
            }
        }

        if (select(maxfd+1, &readset, &writeset, &exset, NULL) < 0) {
            perror("select");
            return;
        }

        if (FD_ISSET(listener, &readset)) {
            struct sockaddr_storage ss;
            socklen_t slen = sizeof(ss);
            int fd = accept(listener, (struct sockaddr*)&ss, &slen);
            if (fd < 0) {
                perror("accept");
            } else if (fd > FD_SETSIZE) {
                close(fd);
            } else {
                make_nonblocking(fd);
                state[fd] = alloc_fd_state();

                char send_buf[1024] = "Connected";
                send(fd, send_buf, 1024, 0);

                assert(state[fd]);/*XXX*/
            }
        }

        for (i=0; i < maxfd+1; ++i) {
            int r = 0;
            if (i == listener)
                continue;

            if (FD_ISSET(i, &readset)) {
                r = do_read(i, state[i]);
            }
            if (r == 0 && FD_ISSET(i, &writeset)) {
                r = do_write(i, state[i]);
            }
            if (r) {
                free_fd_state(state[i]);
                state[i] = NULL;
                close(i);
            }
        }
    }
}
예제 #11
0
void
run(void)
{
    evutil_socket_t sender;
    struct sockaddr_in sin;
    struct event_base *base;
    struct event *write_event = NULL;
    struct event *read_event = NULL;
    struct fd_state *state;
    int result;

    base = event_base_new();
    if (!base)
        return; /*XXXerr*/

    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = 0;
    sin.sin_addr.s_addr = inet_addr("127.0.0.1");
    sin.sin_port = htons(40713);

    sender = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    evutil_make_socket_nonblocking(sender);

#ifndef WIN32
    {
        int one = 1;
        setsockopt(sender, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
    }
#endif

    /*
    if (bind(sender, (struct sockaddr*)&sin, sizeof(sin)) < 0) {
        perror("bind");
        return;
    }

    sender_event = event_new(base, sender, EV_READ|EV_PERSIST, do_read, (void*)base);
    /-*XXX check it *-/
    event_add(sender_event, NULL);
    //*/

    result = connect(sender, (struct sockaddr*)&sin, sizeof(sin));
    if (result < 0 || result == SOCKET_ERROR) {
        if (WSAGetLastError() == WSAEWOULDBLOCK) {
            printf("WSAGetLastError() = WSAEWOULDBLOCK\r\n");
            Sleep(1000);
            printf("Press any key to continue...\r\n");
            //system("pause");
        }
        else {
            printf("connect error!\r\n");
            printf("WSAGetLastError() = 0x%08X\r\n", WSAGetLastError());
            system("pause");
            perror("connect");
            return;
        }
    }

    //printf("Press any key to continue...\r\n");
    //system("pause");

    //write_event = event_new(base, sender, EV_WRITE|EV_PERSIST, do_write, (void*)base);
    //read_event  = event_new(base, sender, EV_READ |EV_PERSIST, do_read,  (void*)base);

    state = alloc_fd_state(base, sender);

    /*
    if (write_event) {
        printf("event_add(write_event, NULL);\r\n");
        event_add(write_event, NULL);
    }
    //*/

    if (state && state->write_event) {
        printf("event_add(state->write_event, NULL);\r\n");
        event_add(state->write_event, NULL);
    }

    if (state && state->read_event) {
        printf("event_add(state->read_event, NULL);\r\n");
        event_add(state->read_event, NULL);
    }

    printf("event_base_dispatch(base);\r\n");
    event_base_dispatch(base);

    /*
    if (write_event)
        event_free(write_event);
    if (read_event)
        event_free(read_event);
    //*/

    if (state)
        free_fd_state(state);
}
예제 #12
0
파일: zeus.c 프로젝트: HardSkript/zeus
void
do_read(evutil_socket_t fd, short events, void *arg)
{
    (void) events;

    struct fd_state *state = arg;
    ssize_t result;

    while (1) {
        assert(state->write_event);
        result = recv(fd, RingBuffer_ends_at(state->buffer), RingBuffer_available_space(state->buffer), 0);
        if (result <= 0)
            break;

        state->rtmp->total_read += result;

        RingBuffer_commit_write(state->buffer, result);
        
        while (RingBuffer_available_data(state->buffer) > 0) {
            RtmpOutputMessage *this_output = rtmp_create_output_message();
            int result_multiplex = rtmp_multiplex(state->rtmp, state->buffer, this_output);
            check(result_multiplex >= 0, "rtmp_multiplex error %d", result_multiplex);

            if (state->rtmp->end == 1) {
                event_del(state->write_event);
                rtmp_destroy_output_message(this_output);
                free_fd_state(state);
                return;
            }

            if (this_output->length > 0) {
                printf("Add block with length=%u\n", this_output->length);
                List_push(state->outputs, this_output);
                assert(state->write_event);
                event_add(state->write_event, NULL);
            } else {
                rtmp_destroy_output_message(this_output);
            }

            if (result_multiplex == 0) break;
        }

        printf("total_read=%u, last_total_read=%u\n", state->rtmp->total_read, state->rtmp->last_total_read);

        if (rtmp_should_acknowledge(state->rtmp) == 1) {
            RtmpOutputMessage *ack = rtmp_create_output_message();
            rtmp_allocate_output_message_content(ack, 16);

            int i = 0;
            unsigned char *msg = ack->message;
            msg[i++] = 0x02;

            msg[i++] = 0x00;msg[i++] = 0x00;msg[i++] = 0x00;
            int_to_byte_array(4, msg, i, 3);i += 3;

            msg[i++] = 0x03;

            msg[i++] = 0x00;
            msg[i++] = 0x00;  
            msg[i++] = 0x00;
            msg[i++] = 0x00;

            // msg[i++] = 0x03;

            // msg[i++] = 0x00;msg[i++] = 0x00;msg[i++] = 0x04;
            // msg[i++] = 0x00;msg[i++] = 0x00;msg[i++] = 0x00;msg[i++] = 0x00;
            // msg[i++] = 0x00;msg[i++] = 0x00;msg[i++] = 0x00;

            int_to_byte_array(state->rtmp->total_read, msg, i, 4);i += 4;

            List_push(state->outputs, ack);
            assert(state->write_event);
            event_add(state->write_event, NULL);

            state->rtmp->last_total_read = state->rtmp->total_read;
        }
    }

    if (result == 0) {
        free_fd_state(state);
    } else if (result < 0) {
        if (errno == EAGAIN) // XXXX use evutil macro
            return;
        perror("recv");
        free_fd_state(state);
    }

error:
    free_fd_state(state);
    return;
}
예제 #13
0
void
WorkerServer::read_callback(evutil_socket_t socket, short event, void *arg)
{
    std::cout << "read callback" << std::endl;

    struct fd_state* state = (struct fd_state*)(arg);

    /* recv json and return ack then download */
    char *buffer;
    char jsonMsgLen[2];
    Json::Reader reader;
    Json::Value  value;

    /* mark is a flag
     * mark = 1 upload    (breakpoint_upload)
     * mark = 2 download  (breakpoint_download)
     * mark = 3 multithread download (file_block_download)
     * */
    int mark = 0;
    std::string md5;
    unsigned long size = 0;
    unsigned long offset = 0;
    unsigned long start = 0;
    unsigned long end = 0;
    int threadNum = 0;

    union Len len;


    /* recv request (json)*/
    /*
     * Json:
     * {
     *      mark:1,     标识
     *      md5:asd7qwebuuaweg12i3ehiqwueh,
     *      size:1900,  文件大小
     *      offset:0,   偏移量  偏移量不为 0 则进行断点上传或下载
     *      thread:1,   多线程下载
     * }
     * */
    /* 先接收 2 字节 json 长度 len,接着接受长度为 len 的 json 串 */
    int ret = recv(socket, jsonMsgLen, 2, MSG_WAITALL);
    if(ret < 0)
    {
        if(errno == EAGAIN && errno == EWOULDBLOCK)
        {
            std::cout << "recv errno" << std::endl;
            free_fd_state(state);
            close(socket);
            return;
        }
    } else if(ret == 0)
    {
        free_fd_state(state);
        return;
    } else {
        len.length = 0;
        len.c[0] = jsonMsgLen[0];
        len.c[1] = jsonMsgLen[1];
        printf("bufferlength:%d\n", len.length);
    }
    if((buffer = (char*)malloc(sizeof(char) * len.length)) == NULL)
    {
        perror("malloc error");
        return;
    }
    /* 即使设置 MSG_WAITALL 标识,不代表能接收 bufferlength 长度的数据包,需自己判定 */
    int recvnum;
    if((recvnum = recv(socket, buffer, len.length, MSG_WAITALL)) == len.length)
    {
        printf("buffer:%s\n", buffer);
        event_del(state->read_event);
    } else {
        free_fd_state(state);
        printf("recv return:%d\n", len.length);
        return;
    }


    /* parse json */
    if(reader.parse(buffer, value))
    {
        if(!value["mark"].isNull())
        {
            mark = value["mark"].asInt();
            md5 = value["md5"].asString();
            threadNum = value["threadNum"].asInt();
            if(mark == 3) {
                start = value["start"].asLargestUInt();
                end = value["end"].asLargestUInt();
                std::cout << "start:" << start << std::endl;
                std::cout << "end:" << end << std::endl;
            } else {
                size = value["size"].asLargestUInt();
                offset = value["offset"].asLargestUInt();
                /* check argument is correct*/
                if(detect_paramenter_correct(mark, md5, size, offset, threadNum) == false) {
                    perror("detect parament error");
                    return;
                }
                std::cout << "size:" << size << std::endl;
                std::cout << "offset:" << offset << std::endl;
            }

            std::cout << "mark:" << mark << std::endl;
            std::cout << "md5:" << md5 << std::endl;
            std::cout << "threadNum:" << threadNum << std::endl;

            /* create handle event */
            Handler handle_event;

            /* parse mark, handler event */
            switch(mark) {
            case 1:
                handle_event = std::make_tuple(WorkerServer::handler_upload, socket, md5, size, offset, threadNum);
                threadpool.AddTask(std::move(handle_event));
                break;
            case 2:
                handle_event = std::make_tuple(WorkerServer::handler_download, socket, md5, size, offset, threadNum);
                threadpool.AddTask(std::move(handle_event));
                break;
            case 3:
                handle_event = std::make_tuple(WorkerServer::file_block_download, socket, md5, start, end, threadNum);
                threadpool.AddTask(std::move(handle_event));
                break;
            default:
                break;
            }
        }
    }
    if(buffer != NULL)
    {
        free(buffer);
    }
}