CAsyncSocket 设置连接超时

hhhh63 2016-12-25 11:15:04
用CAsyncSocket编写一段网络客户端程序,想把连接超时设为750ms,主要代码如下:

// cas.cpp 继承于CAsyncSocket
void cas::OnConnect(int nErrorCode)
{
// 未连网络时,大约20秒以后才到这儿
CAsyncSocket::OnConnect(nErrorCode);
}

// CdDlg.cpp 对话框按钮点击事件
void CdDlg::OnBnClickedOk()
{
AfxSocketInit(); // 初始化通讯
ca.Create(); // 建立通讯,ca 是 cas的实例

// 通过下面语句设置连接超时时间为750ms,实际不起作用,20秒以后才产生连接错误事件
int mytime = 750;
ca.SetSockOpt( SO_SNDTIMEO, &mytime, sizeof(mytime) );
ca.SetSockOpt( SO_RCVTIMEO, &mytime, sizeof(mytime) );

// 连接
ca.Connect(L"192.168.1.241", 9600);
}

通过SetSockOpt设置连接超时时间为750ms,实际不起作用,不管设置什么数值,都是20秒以后才产生连接错误事件。
请高手指点如何解决这个问题。
...全文
433 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
hhhh63 2017-01-07
  • 打赏
  • 举报
回复
引用 9 楼 cutmelon 的回复:
控制connect超时需要用非阻塞socket来处理了,比较简单的
这段程序有两个问题 第17行:BOOL block=FALSE; 设置非阻塞应该改为TRUE 第30行:tv.tv_usec=750; 应该改为750000表示750毫秒,因为单位是微秒。 虽然是小问题,我也找了半天,特此说明。
hhhh63 2016-12-27
  • 打赏
  • 举报
回复
非常感谢 cutmelon 我先试一下,有问题另开贴请教。
cutmelon 2016-12-27
  • 打赏
  • 举报
回复
控制connect超时需要用非阻塞socket来处理了,比较简单的
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <winsock2.h>
#include <windows.h>

#pragma comment(lib,"ws2_32.lib")

int main()
{
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2,2),&wsaData)!=0) return -1;

	//创建socket
	SOCKET s=socket(AF_INET,SOCK_STREAM,0);
	if (s==INVALID_SOCKET) return -1;

	//设置非阻塞
	BOOL block=FALSE;
	ioctlsocket(s,FIONBIO,(unsigned long *)&block);

	//设置连接地址
	SOCKADDR_IN addr;
	memset(&addr,0,sizeof(addr));
	addr.sin_family=AF_INET;
	addr.sin_addr.s_addr=inet_addr("127.0.0.1");
	addr.sin_port=htons(12345);

	//设置等待时间
	struct timeval tv;
	tv.tv_sec=0;
	tv.tv_usec=750;
	struct fd_set wfs;
	FD_ZERO(&wfs);
	FD_SET(s,&wfs);

	//连接
	int len=sizeof(addr);
	connect(s,(SOCKADDR*)&addr,len);

	//等待连接结果
	int ret=select(0,NULL,&wfs,NULL,&tv);
	switch (ret)
	{
	case 0:
		printf("time out\n");
		break;
	case SOCKET_ERROR:
		printf("error\n");
		break;
	default:
		printf("connected\n");
	}

	closesocket(s);

	return 0;
}
  • 打赏
  • 举报
回复
你要自己设置超时的话,就计算在这个时段内没有数据的就算失败,即使有数据也丢掉
赵4老师 2016-12-26
  • 打赏
  • 举报
回复
after connect, WSAConnect, or WSAJoinLeaf was called with a nonblocking, connection-oriented socket. The initial operation returned with a specific error of WSAEWOULDBLOCK, but the network operation went ahead. Whether the operation eventually succeeds or not, when the outcome has been determined, FD_CONNECT happens. The client should check the error code to determine whether the outcome was successful or failed.
赵4老师 2016-12-26
  • 打赏
  • 举报
回复
connect不是send,也不是recv
sevancheng 2016-12-26
  • 打赏
  • 举报
回复
这个好像是设置不了,自己用API来
oyljerry 2016-12-26
  • 打赏
  • 举报
回复
应该有最小值的限制,不是可以任意定制化的
hhhh63 2016-12-26
  • 打赏
  • 举报
回复
引用 4 楼 cvbtvbwu 的回复:
用个定时器吧,设置750毫秒后判断
用定时器试过: void Car::OnTimer() { ASSERT( m_pSocket ); //关闭套接字 if (m_pSocket->m_hSocket != INVALID_SOCKET) m_pSocket->Close(); if(!m_pSocket->create()) { m_nTick = -2; // -2 建立通讯错误 } else { m_pSocket->connect(m_strIP, m_nPort); } // 重设置定时器,设置超时时间 KillTimer( m_nTimer ); m_nTimer = getWnd()->SetTimer( (UINT_PTR)this, m_nOutTime, myTimer ); ASSERT( m_nTimer == (UINT_PTR)this ); } 不起作用,还是要等20秒才能连上。
hhhh63 2016-12-26
  • 打赏
  • 举报
回复
引用 1 楼 chengbar 的回复:
这个好像是设置不了,自己用API来
麻烦指点一下,用API怎么来?
叶恭介叶恭介 2016-12-26
  • 打赏
  • 举报
回复
用个定时器吧,设置750毫秒后判断

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧