SOCKET Open(const char* strIP, UINT nPort, int nTimeOut)
{
SOCKET sockfd = NULL;
do
{
sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockfd <= 0)
{
printf("socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) error=%d
", WSAGetLastError());
break;
}
unsigned long opt = 1;
//set non-blocking
if (ioctlsocket(sockfd, FIONBIO, &opt) < 0)
{
printf("ioctlsocket(FIONBIO, %d) error=%d
", opt, WSAGetLastError());
break;
}
struct sockaddr_in serv_addr;
//以服务器地址填充结构serv_addr
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(strIP);
serv_addr.sin_port = htons(nPort);
if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(struct sockaddr)) == -1)
{
if (WSAGetLastError() == WSAEWOULDBLOCK)
{
int error = -1;
int len = sizeof(int);
timeval tv_timeout;
tv_timeout.tv_sec = 0;
tv_timeout.tv_usec = nTimeOut * 1000;
fd_set set;
FD_ZERO(&set);
FD_SET(sockfd, &set);
if (select(sockfd + 1, NULL, &set, NULL, &tv_timeout) > 0)
{
getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
if(error != 0)
{
break;
}
}
else
{ //timeout or select error
break;
}
}
else
{
printf("connect() error=%d
", WSAGetLastError());
break;
}
}
opt = 0;
//set blocking
if (ioctlsocket(sockfd, FIONBIO, &opt) < 0)
{
printf("ioctlsocket(FIONBIO, %d) error=%d", opt, WSAGetLastError());
break;
}
int iTimeOut = nTimeOut;
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char*)&iTimeOut, sizeof(iTimeOut));
setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char*)&iTimeOut, sizeof(iTimeOut));
return sockfd;
}
while (FALSE);
closesocket(sockfd);
return NULL;
}
用于connect超时控制。
还有不完善的地方。
高手路过,请不吝赐教。