int32 EventLoop::startCtl() { int32 ret = 0; int32 sockets[2]; if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) { NLogError << "EventLoop" << std::hex << this << "create ctl sock fail!"; return -1; } m_ctlfd = sockets[0]; m_ctlfd1 = sockets[1]; setSocketNonblocking(m_ctlfd); setSocketNonblocking(m_ctlfd1); struct epoll_event ev; ev.events = EPOLLIN; ev.data.fd = m_ctlfd; ret = epoll_ctl(m_epl, EPOLL_CTL_ADD, m_ctlfd, &ev); if(ret < 0) { sock_close(m_ctlfd); m_ctlfd = EF_INVALID_SOCKET; sock_close(m_ctlfd1); m_ctlfd1 = EF_INVALID_SOCKET; } return ret; }
int tcpNbReceive (SOCKET fd, char *rcvbuf, int bufsize, int *actrcvnum) { int ret = 0; int readLen = 0; int errcode = 0; if (actrcvnum != NULL) { *actrcvnum = 0; } if (fd == EF_INVALID_SOCKET || rcvbuf == NULL || bufsize <= 0) { return -1; } setSocketNonblocking(fd); readLen = 0; do { ret = recv(fd, rcvbuf, bufsize, 0); if (ret > 0) { readLen += ret; if (actrcvnum != NULL) { *actrcvnum += ret; } rcvbuf += ret; bufsize -= ret; } else if (ret == 0) { /*Socket closed*/ return -1; } else if (ret == SOCKET_ERROR) { errcode = sock_errno; if (errcode == SOCK_EINTR) { continue; } else if (errcode == SOCK_EAGAIN || errcode == SOCK_EWOULDBLOCK) { /*No data can be read*/ break; } else { /*Unexpected error*/ return -1; } } }while(bufsize > 0); return readLen; }
SOCKET tcpNbConnect(const char * dsthost, int dstport, const char * localip, int localport, int * consucc) { SOCKET fd; int ret; struct sockaddr_in cli; int err; int reuseaddr = 1; int keepalive = 1; if (consucc != NULL) { *consucc = 0; } fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (fd == EF_INVALID_SOCKET) { if (consucc != NULL) { *consucc = -1; } return EF_INVALID_SOCKET; } setSocketNonblocking(fd); setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseaddr, sizeof(reuseaddr)); setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&keepalive, sizeof(keepalive)); cli.sin_family = AF_INET; cli.sin_addr = sockGetHostip(dsthost); cli.sin_port = htons(dstport); ret = connect(fd, (struct sockaddr *)&cli, sizeof(struct sockaddr)); if (ret != 0) { err = sock_errno; if (err != SOCK_EINPROGRESS && err != SOCK_EWOULDBLOCK) { if (consucc != NULL) { *consucc = -1; } closesocket(fd); return EF_INVALID_SOCKET; } } return fd; }
int tcpReceive(SOCKET fd, char * rcvbuf, int toread, long waitms, int *actrcvnum) { int ret = 0; int readLen = 0; int errcode = 0; int bytes = 0; int restms = 0; int sval = 0; int usval = 0; int cast_ms = 0; struct timeval tick0; struct timeval tick1; #ifdef LINUX_EPOLL int ep = 0; struct epoll_event ee; struct epoll_event ev_list[16]; #else struct timeval tv; struct timeval *ptv = NULL; fdSet rFDs; #endif if (actrcvnum != NULL) { *actrcvnum = 0; } if (fd == EF_INVALID_SOCKET) { return -1; } if (rcvbuf == NULL || toread <= 0) { return -1; } if (waitms > 0) { gettimeofday(&tick0, NULL); restms = waitms; } setSocketNonblocking(fd); readLen = toread; do { bytes = recv(fd, rcvbuf, readLen, 0); if (bytes > 0) { readLen -= bytes; rcvbuf += bytes; if (actrcvnum != NULL) { *actrcvnum += bytes; } } else if (bytes == -1) { errcode = sock_errno; if (errcode == SOCK_EAGAIN || errcode == SOCK_EWOULDBLOCK || errcode == SOCK_EINTR) { if (waitms > 0) { /*check time out time*/ gettimeofday(&tick1, NULL); usval = tick1.tv_usec - tick0.tv_usec; sval = tick1.tv_sec - tick0.tv_sec; if (usval < 0) { sval -= 1; usval += 1000000; } cast_ms = sval * 1000 + usval / 1000; restms = waitms - cast_ms; if (restms <= 0) { /*time out*/ ret = 0; break; /*break from do {} while*/ } } else if (waitms == 0) { /*restms must be -1 when waitms <= 0*/ restms = -1; } else { restms = -1; } #ifdef LINUX_EPOLL if (ep == 0) { ep = epoll_create(16); if (ep < 0) { return -1; } memset(&ee, 0, sizeof(struct epoll_event)); ee.events = EPOLLIN; ee.data.ptr = NULL; if (epoll_ctl(ep, EPOLL_CTL_ADD, fd, &ee) == -1) { close(ep); return -1; } } ret = epoll_wait(ep, ev_list, (int)128, restms); #else if (restms > 0) { tv.tv_sec = restms / 1000; tv.tv_usec = (restms % 1000) * 1000; ptv = &tv; } else if (restms == 0) { tv.tv_sec = 0; tv.tv_usec = 0; ptv = &tv; } else { /*infinite*/ ptv = NULL; } FD_ZERO(&rFDs); FD_SET(fd, &rFDs); ret = select(fd + 1, &rFDs, NULL, NULL, ptv); #endif /*LINUX_EPOLL*/ if (ret == -1) { errcode = sock_errno; if (errcode == SOCK_EINTR) { continue; } else { ret = -1; break; /*break from do {} while*/ } } else if (ret == 0) { /*time out*/ ret = 0; break; /*break from do {} while*/ } else { #ifdef LINUX_EPOLL if (ev_list[0].events & EPOLLIN) { /*fd can be write*/ continue; } else { ret = -1; break; } #else if (FD_ISSET(fd, &rFDs)) { /*fd can be write*/ continue; } else { ret = -1; break; } #endif } } else { /*Unexpected error*/ ret = -1; break; /*break from do {} while*/ } } else { /*bytes == 0, socket has closed*/ ret = -1; break; } }while (readLen > 0); #ifdef LINUX_EPOLL if (ep != 0) { close(ep); } #endif if (readLen != 0) { return ret; } return toread; }