Ejemplo n.º 1
0
struct NetBase * MallocConnector(const char * ip, const int port) {
    s32 fd;
    struct timeval tv;
    struct sockaddr_in addr;
    struct NetBase * connecter;

    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    if (inet_pton(AF_INET, ip, &addr.sin_addr) <= 0) {
        printf("inet_pton error %s\n", ip);
        return NULL;
    }

    if (-1 == (fd = socket(AF_INET, SOCK_STREAM, 0))) {
        printf("socket create error %s\n", strerror(errno));
        return NULL;
    }

    if (0 != SetNonBlocking(fd) || 0 != SetReuse(fd) || 0 != SetNonNegal(fd)) {
        close(fd);
        return NULL;
    }

    s32 ret = connect(fd, (struct sockaddr *) &addr, sizeof(addr));
    if (ret < 0 && errno != EINPROGRESS) {
        printf("connect error %s\n", strerror(errno));
        close(fd);
        return NULL;
    }
    else {
        connecter = (struct NetBase *)MALLOC(sizeof(struct NetBase));
        connecter->fd = fd;
        connecter->type = BNEV_CONNECT;
        connecter->looper = NULL;
        return connecter;
    }
}
Ejemplo n.º 2
0
void Connector::OnOut() {
    OASSERT(_recvSize > 0 && _sendSize > 0, "buff size is zero");

    SetHardClose(_fd);
    SetNonNegal(_fd);

    Connection * connection = Connection::Create(_fd);
    OASSERT(connection != nullptr, "wtf");

    connection->SetParser(_parser);
    connection->SetBufferSize(_sendSize, _recvSize);

    sockaddr_in local;
    socklen_t len = sizeof(local);
    getsockname(_fd, (sockaddr*)&local, &len);

    connection->SetLocalIp(inet_ntoa(local.sin_addr));
    connection->SetLocalPort(ntohs(local.sin_port));

    connection->SetRemoteIp(_ip);
    connection->SetRemotePort(_port);

    _session->SetFactory(nullptr);
    connection->SetSession(_session);

    NetEngine::Instance()->Del(this, EPOLLOUT);
    NetEngine::Instance()->Remove(this);
    NetEngine::Instance()->Add(connection);
    NetEngine::Instance()->Add(connection, EPOLLIN | EPOLLOUT);

	NetWorker * worker = NetEngine::Instance()->GetWorker();
	worker->Add(connection);

    connection->OnConnected();
    DEL this;
}
Ejemplo n.º 3
0
s32 DispatchLooper(struct NetLooper * looper, const s32 millisecond) {
    struct epoll_event * events = (struct epoll_event *)alloca(sizeof(struct epoll_event) * looper->size);
    memset(events, 0, sizeof(struct epoll_event) * looper->size);
    s32 retCount = epoll_wait(looper->fd, events, looper->size, millisecond);
    if (retCount == -1) {
        if (errno != EINTR) {
            printf("epoll_wait error %d\n", errno);
        }
        return;
    }

    if (retCount == 0)
        return;

    s32 i = 0;
    for (i = 0; i < retCount; i++) {
        s32 code;
        s32 fd;
        struct sockaddr_in addr;
        socklen_t len = sizeof(addr);

        char type = ((struct NetBase *)events[i].data.ptr)->type;
        switch (type) {
        case BNEV_ACCEPT: {
            struct NetBase * accepter = events[i].data.ptr;
            if (events[i].events & (EPOLLERR | EPOLLHUP | EPOLLRDHUP)) {
                code = -1;
                OASSERT(0, "wtf");
            } else if (events[i].events & EPOLLIN) {
                memset(&addr, 0, sizeof(addr));

                s32 i = 0;
                while (i++ < 30 && (fd = accept(accepter->fd, (struct sockaddr *)&addr, &len)) >= 0) {
                    if (0 == SetNonBlocking(fd) && 0 == SetSendBuf(fd, 0) && 0 == SetNonNegal(fd)) {
                        struct NetBase * base = (struct NetBase *)MALLOC(sizeof(struct NetBase));
                        base->fd = fd;
                        base->type = BNEV_IO;
                        base->looper = NULL;
                        base->maxRecvSize = accepter->maxRecvSize;
                        base->maxSendSize = accepter->maxSendSize;
                        if (0 != (*looper->fnAccept)(accepter, base)) {
                            FreeBase(base);
                        }
                    }
                    else {
                        close(fd);
                    }
                }
            }
            break;
        }
        case BNEV_CONNECT: {
            struct NetBase * connecter = events[i].data.ptr;
            if (events[i].events & (EPOLLERR | EPOLLHUP | EPOLLRDHUP))
                code = -1;
            else if (events[i].events & EPOLLOUT)
                code = 0;

            if (UnbindLooper(connecter) != 0) {
                printf("epoll add fd error %s\n", strerror(errno));
                //return;
                OASSERT(0, "wtf");
            }
            connecter->type = BNEV_IO;

            (*looper->fnConnect)(connecter, code);

            if (-1 == code)
                FreeBase(connecter);
            break;
        }
        case BNEV_IO: {
            struct NetBase * base = events[i].data.ptr;
            if (events[i].events & (EPOLLERR | EPOLLHUP | EPOLLRDHUP)) {
                UnbindLooper(base);
                (*looper->fnRecv)(base, -1, NULL, 0);
                FreeBase(base);
                break;
            }

            if (events[i].events & EPOLLIN) {
                s32 res = 0;
                while (1) {
                    u32 size = 0;
                    s32 len = 0;
                    char * buf = RingBufferWrite(base->recvBuff, &size);
                    if (buf && size > 0) {
                        len = recv(base->fd, buf, size, 0);
                        if (len < 0 && errno == EAGAIN)
                            break;
                    }
                    else
                        len = -1;

                    if (len <= 0) {
                        UnbindLooper(base);
                        (*looper->fnRecv)(base, -1, NULL, 0);
                        FreeBase(base);
                        res = -1;
                        break;
                    }

                    if (-1 == (*looper->fnRecv)(base, 0, buf, len)) {
                        UnbindLooper(base);
                        FreeBase(base);
                        res = -1;
                        break;
                    }
                }

                if (-1 == res)
                    break;
            }

            if (events[i].events & EPOLLOUT) {
                if (0 != (*looper->fnSend)(base)) {
                    UnbindLooper(base);
                    FreeBase(base);
                }
            }

            break;
        }
        default:
            OASSERT(0, "wtf");
            break;
        }
    }
}