int NonBlockConnectEx(int sockfd, const struct sockaddr *saptr, socklen_t salen, const int msec, const int conn) { int flags, n, error; socklen_t len; fd_set rset, wset; struct timeval tval; /* 设置为非阻塞的 socket */ flags = fcntl(sockfd, F_GETFL, 0); fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); error = 0; if (conn == 1) { if ((n = connect(sockfd, saptr, salen)) < 0) { if (errno != EINPROGRESS) return ERR_TCPLIB_CONNECT; /* 连接失败 */ } /* Do whatever we want while the connect is taking place. */ if (n == 0) goto done; /* connect completed immediately */ } FD_ZERO(&rset); FD_SET(sockfd, &rset); wset = rset; /* structure assignment */ MsToTimeval(msec, &tval); n = SignalSafeSelect(sockfd+1, &rset, &wset, NULL, msec ? &tval : NULL); if (n == 0) { errno = ETIMEDOUT; return ERR_TCPLIB_TIMEOUT; /* 连接服务器超时 */ } else if (n < 0) return ERR_TCPLIB_OTHERS; /* select()出错 */ if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) { len = sizeof(error); if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) return ERR_TCPLIB_OTHERS; /* Solaris pending error */ } done: fcntl(sockfd, F_SETFL, flags); /* restore file status flags */ if (error) { errno = error; return ERR_TCPLIB_CONNECT; /* 连接服务器失败 */ } return 0; /* 连接服务器成功 */ }
int DoRecvData(int sockfd, void *buf, const size_t len, int msec) { struct timeval tv; fd_set rset; int rv; int rc; MsToTimeval(msec, &tv); FD_ZERO(&rset); FD_SET(sockfd, &rset); rv = SignalSafeSelect(sockfd+1, &rset, NULL, NULL, msec ? &tv : NULL); if (rv < 0) return ERR_TCPLIB_OTHERS; /* some error occured */ if (rv == 0) return ERR_TCPLIB_TIMEOUT; /* timed out */ if (FD_ISSET(sockfd, &rset)) { /* 一次接收所有数据 */ rc = recv(sockfd, buf, len, 0); return rc; /* return bytes had received */ } return 0; /* nothing had received */ }
int DoSendData(int sockfd, const void *buf, const size_t len, int msec) { struct timeval tv; fd_set wset; int rv; int wc; MsToTimeval(msec, &tv); FD_ZERO(&wset); FD_SET(sockfd, &wset); rv = SignalSafeSelect(sockfd+1, NULL, &wset, NULL, &tv); if (rv < 0) return ERR_TCPLIB_OTHERS; /* some error occured */ if (rv == 0) return ERR_TCPLIB_TIMEOUT; /* timed out */ if (FD_ISSET(sockfd, &wset)) { /* 一次发送所有数据 */ wc = send(sockfd, buf, len, 0); return wc; /* return bytes had sent */ } return 0; /* nothing had sent */ }