阻塞和非阻塞模式的转换问题

caoyiwen19830726 2009-02-12 02:45:09
下面这段代码先把套接字设置为非阻塞模式,然后又设置为阻塞模式,其中的原因是什么? 还有就是,中间标注的那段代码的含义是什么?请高手帮我解释一下,谢谢!
{
......
m_SttnEqpSocket = socket(AF_INET, SOCK_STREAM, 0);
if( m_SttnEqpSocket < 0 )
{
TRACE("socket()[%d]\n", WSAGetLastError() );
return(-1);
}

//设置为非阻塞模式
nonblocking = 1;
if(ioctlsocket(m_SttnEqpSocket, FIONBIO, (unsigned long*)&nonblocking) == SOCKET_ERROR)
{
TRACE("ioctlsocket1()[%d]\n", GetLastError());
return(-1);
}

memset(&ServAddr, 0, sizeof(struct sockaddr_in));
ServAddr.sin_family = AF_INET;
ServAddr.sin_port = htons((u_short)nPORT);
ServAddr.sin_addr.s_addr = inet_addr(strIP_ADDR);

/* 2. connect the server */
nRet=connect(m_SttnEqpSocket, (LPSOCKADDR)&ServAddr,(int)sizeof(ServAddr));
if ( (nRet== SOCKET_ERROR) && (WSAGetLastError() != WSAEWOULDBLOCK) )
{
TRACE("connect()[%d]\n", GetLastError() );
Disconnect();
return (-1);
}

/* 3. select */
FD_ZERO(&wset);
FD_SET(m_SttnEqpSocket, &wset);
tval.tv_sec = CONNECT_TIME_OUT;
tval.tv_usec = 0;

if ( (nRet = select((int)m_SttnEqpSocket+1, NULL, &wset, NULL, &tval)) == 0)
{
/* connect timeout */
TRACE("Connect timeout! [%s:%d]\n", strIP_ADDR, nPORT );
Disconnect();
return (-1);
}

--------------------------------------------------------------------------------------------------标注的这段的意义是什么??
if (FD_ISSET(m_SttnEqpSocket, &wset))
{
nLen = sizeof(nError);
if (getsockopt(m_SttnEqpSocket, SOL_SOCKET, SO_ERROR , (char*)&nError, &nLen) < 0) {
/* pending error */
TRACE("getsockopt1()[%d] pending error\n", GetLastError() );
Disconnect();
return (-1);
}

if (nError)
{
TRACE("getsockopt2()[%d] nError[%d]\n", GetLastError(), nError );
Disconnect();
return (-1);
}
}
else
{
/* select error: m_hSocket not set */
Disconnect();
return (-1);
}
----------------------------------------------------------------------------------------------------------------

//设置为阻塞模式
nonblocking =0;
if(ioctlsocket(m_SttnEqpSocket, FIONBIO, (unsigned long*)&nonblocking) == SOCKET_ERROR)
{
TRACE("ioctlsocket2()[%d]\n", GetLastError() );
return(-1);
}

TRACE("Info : [%s:%d] connected.\n", strIP_ADDR, nPORT);

return NOERROR;
}
...全文
517 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
Garfield 2009-02-20
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 caoyiwen19830726 的回复:]
我发的这段代码是客户端的,还有一个问题就是WSAEWOULDBLOCK错误是不是仅在非阻塞模式中才发生?
[/Quote]

哇,不得了啊不得了,你有道灵
光从天灵盖喷出来,你知道嘛,年纪轻轻的就有一身横练的筋骨,简直百年一见的编程奇才啊,如果有一天让你打通任督二脉,你还不飞龙上天,正所谓我不入地 狱,谁入地狱……警恶惩奸,维护世界和平这个任务就交给你了,好嘛?

我这里有本牛人十日速成是家传秘籍

看你有缘 就收你 10块怎么样啊

当然没那么多钱可以按揭

那不然呢?诶,同学,学习需要个过程。。

当你需要做的项目有更多的需求的时候,你就会去找解决问题的方法,然后你就会发现原来阻塞和非阻塞的关系。。。

不能光看代码不练。
Garfield 2009-02-20
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 caoyiwen19830726 的回复:]
我把套接字设为非阻塞和阻塞的那两段代码注释掉后,也没有发现对程序有什么影响,这是怎么回事?
[/Quote]

能连上就没影响
不能连上你自己看看超时时间有什么不同。
caoyiwen19830726 2009-02-15
  • 打赏
  • 举报
回复
up
caoyiwen19830726 2009-02-13
  • 打赏
  • 举报
回复
为什么用阻塞模式便于收发,可以解释一下吗,我这块不太清楚,谢谢了!
caoyiwen19830726 2009-02-13
  • 打赏
  • 举报
回复
我发的这段代码是客户端的,还有一个问题就是WSAEWOULDBLOCK错误是不是仅在非阻塞模式中才发生?
caoyiwen19830726 2009-02-13
  • 打赏
  • 举报
回复
做为一个大型的服务器,肯定是不能只为一个客户端服务,这个是时候肯定是非阻塞的

可是程序的最后为什么又变成了阻塞了的呢?
lijianli9 2009-02-13
  • 打赏
  • 举报
回复
我把套接字设为非阻塞和阻塞的那两段代码注释掉后,也没有发现对程序有什么影响,这是怎么回事?
说明你还没有从大局观去理解,应用阻塞和非阻塞的程序,做为一个大型的服务器,肯定是不能只为一个客户端服务,
这个是时候肯定是非阻塞的,你可以多看写阻塞和非阻塞的例子去体会下。总之阻塞和非阻塞也可以在程序中混用。
caoyiwen19830726 2009-02-13
  • 打赏
  • 举报
回复
我把套接字设为非阻塞和阻塞的那两段代码注释掉后,也没有发现对程序有什么影响,这是怎么回事?
Evenque 2009-02-12
  • 打赏
  • 举报
回复
学习一下
Garfield 2009-02-12
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 caoyiwen19830726 的回复:]
阻塞21sec?在哪里有提到呢?没有发现啊。
还有就是,用非阻塞+select自定义timeval超时去检测,那为什么还要在最后设置为阻塞模式呢?谢谢啦
[/Quote]

1.自己去测试或google
2.仔细看2楼我的回复
caoyiwen19830726 2009-02-12
  • 打赏
  • 举报
回复
阻塞21sec?在哪里有提到呢?没有发现啊。
还有就是,用非阻塞+select自定义timeval超时去检测,那为什么还要在最后设置为阻塞模式呢?谢谢啦
百事烟 2009-02-12
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 Garfield 的回复:]
那就是因为他觉得阻塞用着收发爽
[/Quote]
哈哈!!
Garfield 2009-02-12
  • 打赏
  • 举报
回复
最后又设为阻塞
那就是因为他觉得阻塞用着收发爽,但是connect超时太久不爽。
以上。

tval.tv_sec = CONNECT_TIME_OUT;
Garfield 2009-02-12
  • 打赏
  • 举报
回复 1
下面这段代码先把套接字设置为非阻塞模式,然后又设置为阻塞模式,其中的原因是什么?

1.connect的时候如果连不上会阻塞21sec,他想自定义超时时间,因此用非阻塞+select自定义timeval超时去检测。

还有就是,中间标注的那段代码的含义是什么?请高手帮我解释一下,谢谢!

2.
if (socket句柄可写) // 连上了
{
if (!获取socket错误)
{
jjyy();
}

if (socket有错误)
{
jjyy();
}

} else { // 没连上
{
jjyy();
}
}


有点多余了,其实用wsagetlasterror()就ok。

18,356

社区成员

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

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