1、通过设置套接字的属性,把其从阻塞模式改为非阻塞模式,即使没有数据到来或者连接建立,程序也不会一直等待,而是立刻返回。
2、超时机制:在代码中设置超时机制,即如果套接字在指定时间内依然处于阻塞状态,则退出程序。
3、信号处理:使用信号处理机制,在另一个线程中发送一个指定的信号,如SIGINT信号,当程序接收到该信号时,可以退出当前的阻塞状态。
提供借鉴:阻塞SOCKET的非阻塞连接//用非阻塞方式连接,这样的话,一旦连接不上,界面不会出现一段较长时间不响应。
int tcp_connect(char *ip, int port, struct timeval *timeout)
{
struct linger opt
struct sockaddr_in sin
struct linger lg
int sock
int nodelay
unsigned long ul
fd_set fdConnect
memset(&lg, 0, sizeof(struct linger))
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
if (sock == INVALID_SOCKET)
{
TRACE("socket errno:\t%d\n", WSAGetLastError())
return -1
}
ul = 1
if (ioctlsocket(sock, FIONBIO, &ul) == SOCKET_ERROR)
{
TRACE("ioctlsocket errno:\t%d\n", WSAGetLastError())
goto err_exit
}
memset(&sin, 0, sizeof(sin))
sin.sin_family = AF_INET
sin.sin_addr.S_un.S_addr = inet_addr(ip)
sin.sin_port = htons(port)
if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) == 0)
{
goto ONCE_SUC
}
FD_ZERO(&fdConnect)
FD_SET((unsigned int)sock, &fdConnect)
if (select(0, 0, &fdConnect, 0, timeout) <= 0)
{
TRACE("select errno:\t%d\n", WSAGetLastError())
goto err_exit
}
ONCE_SUC:
ul = 0
if (ioctlsocket(sock, FIONBIO, &ul) == SOCKET_ERROR)
{
TRACE("ioctlsocket errno:\t%d\n", WSAGetLastError())
goto err_exit
}
/*消除滞留*/
memset(&opt, 0, sizeof(struct linger))
if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (char*)&opt, sizeof(opt)) == SOCKET_ERROR)
{
TRACE("SO_LINGER errno:\t%d\n", WSAGetLastError())
}
/*禁用合并*/
nodelay = 1
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*) &nodelay, sizeof(int)) == SOCKET_ERROR)
{
TRACE("TCP_NODELAY errno:\t%d\n", WSAGetLastError())
}
return sock
err_exit:
closesocket(sock)
return -1
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)