阻塞套接字巧妙设置连接超时

130 篇文章 0 订阅
28 篇文章 0 订阅

    最近开发设备控制程序的过程中遇到一个问题,由于流程控制需要,必须使用阻塞的TCP套接字,正常使用没有什么问题,但是如果目标IP不存在,或者无效,则connect的等待时间很长,测试大概为20S左右,这个响应时间是无法容忍的,因此必须进行优化,开始考虑Ping这个地址,如果主机有回应,再去连接,否则就不进行连接,但是考虑到防火墙的原因,这个未必能达到我们的要求,BAIDU了一下,发现了一个好办法,就是用select去阻塞,等待套接字可写,这个超时时间是我们可以设置的。具体做法是先设置套接字为非阻塞的套接字,然后select去等待套接字可写,然后再将套接字设为非阻塞的。

具体做法见代码:

//设置非阻塞方式连接 
	unsigned   long   ul   =   1; 
	int iRet   =   ioctlsocket(hSocket,   FIONBIO,   (unsigned   long*)&ul); 

	if(iRet == SOCKET_ERROR)
	{
		ATLTRACE("设置非阻塞套接字失败deviceInd = %d\n", deviceInd); ;
	}

	ZeroMemory(&svrsockaddr, sizeof sockaddr_in);
	svrsockaddr.sin_family      = AF_INET;
	svrsockaddr.sin_addr.S_un.S_addr = htonl(dwAddr);
	svrsockaddr.sin_port	       = htons(nTxPort);
	iRet = connect(hSocket,(sockaddr*)(&svrsockaddr),sizeof(svrsockaddr));

	//select   模型,即设置超时 
	struct   timeval   timeout; 
	fd_set   r; 

	FD_ZERO(&r); 
	FD_SET(hSocket,   &r); 
	timeout.tv_sec   =   3;   //连接超时3秒 
	timeout.tv_usec   =0; 
	iRet   =   select(0,  0, &r, 0, &timeout); 

	if ( iRet <=  0)
	{ 
		m_bIsConnectDevice[deviceInd] = false;
		ATLTRACE("等待连接超时失败deviceInd = %d\n", deviceInd); 
	} 
	else
	{
		//一般非锁定模式套接比较难控制,可以根据实际情况考虑   再设回阻塞模式 
		unsigned   long   ul1=   0; 
		iRet   =   ioctlsocket(hSocket,   FIONBIO,   (unsigned   long*)&ul1); 

		if(iRet == SOCKET_ERROR)
		{
			ATLTRACE("设置阻塞套接字失败deviceInd = %d\n", deviceInd); ;
		}

		m_bIsConnectDevice[deviceInd] = (SOCKET_ERROR != iRet);
		m_bIsGetDeviceReady = FALSE;
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值