gadfly 回复于:2003-08-11 14:40:32 |
这两个都可以用非阻塞socket,select控制超时 |
yuanyawei 回复于:2003-08-12 09:08:00 |
我觉得第一种情况用select可以很好解决。
但第二种情况在遇到客户端直接拔网线的情况时,server端的情况较难判断,要看内核的参数,linux下较好处理,BSD也没问题,HP和AIX也能处理,但SCO下就不好办了(参数老调不好)。 |
minsky 回复于:2003-08-12 10:52:27 |
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()的返回值来判断网络情况; |
calfen 回复于:2003-12-18 15:18:55 |
unp上明确说setsockopt只能用在读写时候不能用在connect上啊... |
grouploo 回复于:2004-06-25 23:06:35 |
/********************************************/
/**** 作者::夕君 **/ /**** 时间: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; } |