CSocket怎么设置连接超时?

lsxsxs 2010-09-29 10:24:16
写了个网络程序,在MFC做的,用了CSocket,都做完了,才发现如果在连接的IP不存在的情况下,需要等待20秒左右才会返回连接错误。在不改成CAsyncSocket的情况下,能设置连接超时吗?在网上搜了无数种方法来设置连接超时,都不管用,仍然是要等20秒。
即便是我用了个Timer来返回,也是要等到20秒之后才执行。
比如,我用一个变量 int a = 0;如果连接成功时令a=1。用Timer过3秒检测a的值。我是先SetTimer,然后再Connect的。
但是我发现,SetTimer中的事件是要等到Connect返回了值之后才开始执行的。也就是如果连接的IP不存在,仍然要先等20秒。
谁能指点一下吗?先谢谢了。
...全文
382 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
oper09 2013-04-12
  • 打赏
  • 举报
回复
引用 10 楼 xgPaul 的回复:
引用 7 楼 lsxsxs 的回复:再问一个很弱的问题,怎么从CSocket* 转化为SOCKET CSocket* 转化为SOCKET有何用?强制转换。。。
SOCKET保存了套接字信息,可以用Detach()的方法提取SOCKET,下次使用时可以用Attach()方法
SOCKET g_socket;
///
CSocket m_clientSocket;
///
g_socket = m_clientSocket.Detach();
///其它线程
CSocket socket;
socket.Attach(g_socket);
////
xgPaul 2010-09-29
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 lsxsxs 的回复:]
再问一个很弱的问题,怎么从CSocket* 转化为SOCKET
[/Quote]
CSocket* 转化为SOCKET有何用?强制转换。。。
lsxsxs 2010-09-29
  • 打赏
  • 举报
回复
setsockopt 似乎没用吧,我在网上看说setsockopt不支持SO_RCVTIMEO类型
lsxsxs 2010-09-29
  • 打赏
  • 举报
回复
再问一个很弱的问题,怎么从CSocket* 转化为SOCKET
重复的昵称嘛 2010-09-29
  • 打赏
  • 举报
回复
嗯,需要了解 Socket的阻塞和非阻塞模式...
huzhibin2000 2010-09-29
  • 打赏
  • 举报
回复
在建立好socket之后,调用connect之前,先设置socket为非阻塞模式。
还是给你个例子吧

int TCP_Connect(const char *serverIP, int port, int iTimeOut)
{
struct timeval tv;
int error;
fd_set writefds;
struct sockaddr_in servaddr;
int ret;
u_long ul = 1;//设置非阻塞方式连接
BOOL bNodelay = TRUE;

//1.socket
int fd = socket(PF_INET,SOCK_STREAM, 0);
if(fd <=0 )
{
LogError("create socket failed.%s", strerror(errno));
fd = 0;
return -1;
}

//2.fcntl
#ifdef LINUX_PLATFORM

fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);

#else
if(ioctlsocket(fd, FIONBIO, (unsigned long*)&ul) != 0)
{
LogError("ioctlsocket socket failed:%ld", GetLastError());
}
#endif


//3.connect
//bzero(&servaddr, sizeof(servaddr));
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
#ifdef LINUX_PLATFORM
inet_aton((const char*)serverIP, &servaddr.sin_addr);
#else
servaddr.sin_addr.S_un.S_addr = inet_addr(serverIP);
#endif
servaddr.sin_port = htons(port);
if(iTimeOut <= 0)
{
iTimeOut = 5;
}

if(connect(fd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
{ //if(connect failed)
#ifdef LINUX_PLATFORM
if (errno == EINPROGRESS)
#else
ret = GetLastError();
if(ret == WSAEINPROGRESS || ret == WSAEWOULDBLOCK)
#endif
{// if it is in the connect process
while(1)
{
tv.tv_sec = iTimeOut;
tv.tv_usec = 0;
FD_ZERO(&writefds);
FD_SET((u_long)fd, &writefds);
if( select(fd + 1, NULL, &writefds, NULL, &tv) > 0 )
{
int len = sizeof(int);
//skip the firewall setting.
getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
if(error == 0)
ret = 0;
else
ret = -1;
break;
}
else
{
#ifdef LINUX_PLATEFORM
if(errno == EINTR || errno == EAGAIN )
continue;
#endif

LogError("connect time out.");

ret = -1;//timeout or error happen
break;//
}
}
}//end if it is in the connect process
else
{
ret = -1;
}
}//end if(connect failed)
else ret = 0;

if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&bNodelay, sizeof(bNodelay) ) != 0)
{
LogError("setsockopt socket failed.%s", strerror(errno));
return -3;
}

if(ret < 0)
{
#ifdef LINUX_PLATFORM
close(fd);
#else
closesocket(fd);
#endif
fd = 0;
LogError("connect %s failed, errno:%d.", serverIP, errno);
return ret;
}

return fd;
}
Eleven 2010-09-29
  • 打赏
  • 举报
回复
Sorry
return setsockopt(s, SOL_SOCKET, bRecv ? SO_RCVTIMEO : SO_SNDTIMEO, (char*)&nTime, sizeof(nTime));
-->
return SOCKET_ERROR != setsockopt(s, SOL_SOCKET, bRecv ? SO_RCVTIMEO : SO_SNDTIMEO, (char*)&nTime, sizeof(nTime));
Eleven 2010-09-29
  • 打赏
  • 举报
回复
BOOL SetTimeOut(SOCKET s, int nTime, BOOL bRecv)
{
return setsockopt(s, SOL_SOCKET, bRecv ? SO_RCVTIMEO : SO_SNDTIMEO, (char*)&nTime, sizeof(nTime));
}
shenyi0106 2010-09-29
  • 打赏
  • 举报
回复
int setsockopt(
SOCKET s,
int level,
int optname,
const char* optval,
int optlen
);

SO_RCVTIMEO int Receives time-out in milliseconds (available in the Microsoft implementation of Windows Sockets 2).
SO_SNDTIMEO int Sends time-out in milliseconds (available in the Microsoft implementation of Windows Sockets 2).

Tinyftpd是用C语言实现的简单、快速、高效的Linux FTP服务器,只需简单的配置,就可快速的将主机变成高效的FTP服务器。模块简介TinyFTP分为 字符串工具模块、参数配置模块、socket模块、内部进程间通讯模块、系统调用工具模块。字符串工具模块:字符串模块主要用来处理开发过程中,各种对字符串的处理。模块在string.h 与 string.c参数配置模块:参数配置模块提供参数配置的功能。具体在parseconf.h 和 parseconf.csocket模块:用于socket通讯建立与数据传输。可见 commonsock.h commonsock.c内部进程间通讯模块:用于子进程 与 父进程间的通讯 与数据传输。privsock.h 和 privsock.c系统调用工具模块:主要是一些用到的系统调用的函数封装。可见sckutil.h sckutil.c安装编译cd build/ chmod  x bulid.sh sudo ./build.sh运行cd /bin sudo ./tinyftpd配置配置文件在当前目录的tinyftpd.conf配置参数说明tunable_pasv_enable是否开启被动模式tunable_port_enable是否开启主动模式tunable_max_clients最大连接数tunable_max_per_ip每IP最大连接数tunable_listen_portFTP服务器端口tunable_accept_timeoutaccept超时间tunable_connect_timeoutconnect超时间tunable_idle_session_timeout控制时间连接超时tunable_data_connection_timeout数据连接时间超时tunable_local_umask掩码tunable_upload_max_rate最大上传速度(byte/s)tunable_download_max_rate最大下载速度(byte/s)tunable_listen_addressFTP服务器IP地址 标签:Tinyftpd

16,467

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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