参考gsoap库
fd = (int)socket(AF_INET, SOCK_STREAM, 0);
if (soap->connect_timeout)
fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)|O_NONBLOCK);
for (;;)
{
//连接服务器失败
if (connect((SOAP_SOCKET)fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr)))
{
//如果设置了连接超时时间
if (soap->connect_timeout && (soap_socket_errno == SOAP_EINPROGRESS
|| soap_socket_errno == SOAP_EWOULDBLOCK))
{
struct timeval timeout;
size_t n = sizeof(struct sockaddr_in);
fd_set fds;
if (soap->connect_timeout > 0)
{ timeout.tv_sec = soap->connect_timeout;
timeout.tv_usec = 0;
}
else
{ timeout.tv_sec = -soap->connect_timeout/1000000;
timeout.tv_usec = -soap->connect_timeout%1000000;
}
FD_ZERO(&fds);
FD_SET((SOAP_SOCKET)fd, &fds);
//select 当写事件发生或者超时事件发生则不在阻塞
//如果超时则返回0
for (;;)
{
int r = select((SOAP_SOCKET)(fd + 1), NULL, &fds, NULL, &timeout);
if (r > 0)
break;
if (!r)
{
soap->errnum = 0;
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connect timeout\n"));
soap_set_sender_error(soap, "Timeout", "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR);
soap->fclosesocket(soap, (SOAP_SOCKET)fd);
return SOAP_INVALID_SOCKET;
}
if (soap_socket_errno != SOAP_EINTR)
{
soap->errnum = soap_socket_errno;
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
soap_set_sender_error(soap, tcp_error(soap), "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR);
soap->fclosesocket(soap, (SOAP_SOCKET)fd);
return SOAP_INVALID_SOCKET;
}
}
//若无错误发生,getsockopt()返回0
n = sizeof(soap->errnum);
if (!getsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_ERROR, (char*)&soap->errnum, &n) && !soap->errnum)
break;
soap->errnum = soap_socket_errno;
soap_set_sender_error(soap, tcp_error(soap), "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR);
soap->fclosesocket(soap, (SOAP_SOCKET)fd);
return SOAP_INVALID_SOCKET;
}
else if (soap_socket_errno != SOAP_EINTR)
{ soap->errnum = soap_socket_errno;
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
soap_set_sender_error(soap, tcp_error(soap), "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR);
soap->fclosesocket(soap, (SOAP_SOCKET)fd);
return SOAP_INVALID_SOCKET;
}
}
else
break;
}
//执行此次表示已经连接成功
if (soap->connect_timeout)
fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK);
soap->socket = fd;