用fcntl设定socket为非阻塞
来源:互联网 发布:算法统宗pdf下载 编辑:程序博客网 时间:2024/06/11 21:30
第一部分
-------------------------------------------------------------------------------------------------------------------
How would I put my socket in non-blocking mode?
From Andrew Gierth (andrew@erlenstar.demon.co.uk):
Technically, fcntl(soc, F_SETFL, O_NONBLOCK) is incorrect since it clobbers all other file flags. Generally one gets away with it since the other flags (O_APPEND for example) don't really apply much to sockets. In a similarly rough vein, you would use fcntl(soc, F_SETFL, 0) to go back to blocking mode.
To do it right, use F_GETFL to get the current flags, set or clear the O_NONBLOCK flag, then use F_SETFL to set the flags.
And yes, the flag can be changed either way at will.
From: jagadeesh
Code:
/* set socket to non-blocking i/o */
sts = ioctl(ccp->main_sock, FIONBIO, (char *)&one);
if (sts)
{
setproderr(PE_TCPERROR, GEL_FATAL);
sprintf(line,"ioctl (main) failed - %s",strerror(errno));
tcpabort();
}
From: Viswaroopan
Hi,
I tried this and works great as non-blocking socket. I have a different problem is that, when I made it as non-blocking the accept() on the server comes out immediately with non-block error. Instead I want accept() to wait for some time (set a timeout) before giving that error. Is there any way I can set the timeout on accept().
Thanks in advance.
Vish
From: Jonathan Rynd
This is normal for all socket nonblocking operations: if you call them, you should be prepared to handle 2 cases: 1, they succeed right away, 2, they 'fail' with the "EWOULDBLOCK" non-blocking error (it's not a real failure, it just means "we can't satisfy that right now'. You then have to create a FD_SET structure and use it as input to select() with the proper timeout. See the manpage for select. Depending on the call, when select() returns to indicate success, you may need to make the call again.
From:
sorry, but a little more source code would help me more cause i do know nothing about ioctl and need a nonblocking socket...
cause i want to have a read, that doesent stop the whole program
and, what about this stuff with select()
how do i get a buffer that stores a recived package and give it to me when i ask, if there is a new one, or says no, there is no new package, if there is none
From: jesus
aehrm forgot my email...
sorry, but a little more source code would help me more cause i do know nothing about ioctl and need a nonblocking socket...
cause i want to have a read, that doesent stop the whole program
and, what about this stuff with select()
how do i get a buffer that stores a recived package and give it to me when i ask, if there is a new one, or says no, there is no new package, if there is none
From: Michael Lampkin
Added on: 2002-06-01 00:53:57
Since this is a common question... the follow is sample code showing setting and un-setting for non-blocking on a socket.
Code:
int flags;
/* Set socket to non-blocking */
if ((flags = fcntl(sock_descriptor, F_GETFL, 0)) < 0)
{
/* Handle error */
}
if (fcntl(socket_descriptor, F_SETFL, flags | O_NONBLOCK) < 0)
{
/* Handle error */
}
/* Set socket to blocking */
if ((flags = fcntl(sock_descriptor, F_GETFL, 0)) < 0)
{
/* Handle error */
}
if (fcntl(socket_descriptor, F_SETFL, flags & (~O_NONBLOCK)) < 0)
{
/* Handle error */
}
第二部分
-------------------------------------------------------------------------------------------------------
1)connect超时:
1)setsockopt();//将socket置为非阻塞模式;
2)connect();
3)判断connect()的返回值,一般情况会返回-1,这时你还必须判断错误码如果是EINPROGRESS,那说明connect还在继续;如果错误码不是前者那么就是有问题了,不必往下执行,必须关掉socket;待下次重联;
4)select();设置好函数中的超时时间,将select()中的read和write项置上,在超时时间内,如果select返回1,即描述字变为了可写,那么连接成功;如果返回2,即描述字变为即可读又可写,那么出错;如果返回0,那么超时;
============================================
2.网络中断:
如果你的程序是客户端.用select检查描述符的状态,如果可读就recv(),根据recv()的返回值来判断网络情况;
/********************************************/
/**** 作者::夕君 **/
/**** 时间:2004.04.04 **/
/**** 北京金万维科技 http://www.gnway.com **/
/*******************************************/
/*此函数实现判断m_server的m_port端口是否可以连上,超时限制为nTimeOut秒*/
BOOL ConnectTest(char * m_server,int m_port)
{
struct hostent* host = NULL;
struct sockaddr_in saddr;
unsigned int s = 0;
BOOL ret;
time_t start;
int error;
host = gethostbyname (m_server);
if (host==NULL)return FALSE;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(m_port);
saddr.sin_addr = *((struct in_addr*)host->h_addr);
if( (s=socket(AF_INET, SOCK_STREAM, 0))<0){
return FALSE;
}
fcntl(s,F_SETFL, O_NONBLOCK);
if(connect(s,(struct sockaddr*)&saddr, sizeof(saddr)) == -1) {
if (errno == EINPROGRESS){// it is in the connect process
struct timeval tv;
fd_set writefds;
tv.tv_sec = m_nTimeOut;
tv.tv_usec = 0;
FD_ZERO(&writefds);
FD_SET(s, &writefds);
if(select(s+1,NULL,&writefds,NULL,&tv)>0){
int len=sizeof(int);
//下面的一句一定要,主要针对防火墙
getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &len);
if(error==0) ret=TRUE;
else ret=FALSE;
}else ret=FALSE;//timeout or error happen
}else ret=FALSE;
}
else ret=TRUE;
close(s);
return ret;
}
- 用fcntl设定socket为非阻塞
- 用fcntl设定socket为非阻塞
- Socket,非阻塞,fcntl
- Linux,socket,非阻塞,fcntl
- Linux,socket,非阻塞,fcntl
- Linux下socket设置为非阻塞方式和fcntl系统调用
- Linux下socket设置为非阻塞方式和fcntl系统调用
- Linux下socket设置为非阻塞方式和fcntl系统调用
- Linux下socket设置为非阻塞方式和fcntl系统调用
- 非阻塞IO--fcntl
- 高级套接字函数 fcntl 设置socket 非阻塞
- 设置socket为非阻塞
- NDK socket 非阻塞方式设定 以及 返回值
- 如何设置linux socket为非阻塞
- 阻塞非阻塞socket
- socket阻塞,非阻塞
- socket设置为非阻塞方式&阻塞方式
- 使用fcntl函数将套接字设为非阻塞式I/O
- 上班人员必读:“五险一金”详解[zz]
- XSLT 元素参考 函数
- .net题目(2)
- .net题目(3)
- oracle SQL性能优化
- 用fcntl设定socket为非阻塞
- 关于os认证和口令文件认证(转)
- C++ 基类和派生类
- Sql Server中的日期与时间函数
- .net题目(四)
- C# QQ EMAIL 邮件批量 发送程序. 狂
- 字符串的一些收集
- 评《Visual Basic 2005 文件IO与数据存取秘诀》
- net题目(5)