中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > C/C++
大家来探讨一下socket连接超时的问题
作者:未知 时间:2005-09-13 19:24 出处:ChinaUnix.net 责编:chinaitpower
              摘要:大家来探讨一下socket连接超时的问题

[size=18:ac54d21053]在客户端与服务器端通过socket连接时,有两个问题必须考虑
1、connect连接时可能会发生连接不上的情况,需要实现超时退出程序。
2、连接后在接收数据的过程中,可能发生网络中断,不能接受数据的情况,需要退出程序。

这两个问题应该很常见,希望高手给大家详细地讲解一下,谢谢。[/size:ac54d21053]

 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;


}

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有