TcpConnection* TcpConnector::connect(const TcpSockAddr& addr, int &ret, long timeout) { int sockfd; ret = -1; sockfd = socket(addr.ai_family, SOCK_STREAM, 0); if (sockfd < 0) return 0L; if (timeout < 0) ret = ::connect(sockfd, (struct sockaddr*)&addr.ai_addr, addr.ai_addrlen); else ret = timeout_connect(sockfd, (struct sockaddr*)&addr.ai_addr, addr.ai_addrlen, timeout); if (ret < 0) { close(sockfd); return 0L; } else { TcpConnection *tcon; tcon = new TcpConnection; if (tcon->set_fd(sockfd) < 0) { delete tcon; return 0L; } else { return tcon; } } }
TcpConnection* TcpConnector::connect(const Address& addr, int& ret, long timeout) { int sockfd; struct addrinfo *res; res = addr.addr; ret = -1; if (res == NULL) return 0L; do { sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (sockfd < 0) continue; if (timeout < 0) { if ((ret=::connect(sockfd, res->ai_addr, res->ai_addrlen)) == 0) break; } else { if ((ret=timeout_connect(sockfd, res->ai_addr, res->ai_addrlen, timeout)) == 0) break; } close(sockfd); } while ((res = res->ai_next) != NULL); if (res) { TcpConnection *tcon; tcon = new TcpConnection; if (tcon->set_fd(sockfd) < 0) { delete tcon; return 0L; } else { return tcon; } } else { return 0L; } }
TcpConnection* TcpAcceptor::accept(int &ret, long timeout) { struct timeval *ptimeout; struct timeval time; fd_set r_fdset; int conn_fd; TcpConnection *conn; if (timeout < 0) { // block ptimeout = NULL; } else { time.tv_sec = timeout; time.tv_usec = 0; ptimeout = &time; } while (1) { FD_ZERO(&r_fdset); FD_SET(listen_fd, &r_fdset); switch (select(listen_fd + 1, &r_fdset, NULL, NULL, ptimeout)) { case 0: ret = E_TIMEOUT; return 0L; case -1: ret = -1; return 0L; default: if (FD_ISSET(listen_fd, &r_fdset)) break; else continue; } break; } if ((conn_fd=::accept(listen_fd, NULL, NULL)) < 0) { ret = -1; return 0L; } conn = new TcpConnection; if (conn->set_fd(conn_fd) < 0) { delete conn; return 0L; } else { return conn; } }