getsockopt如何判断socket已经断开

getsockopt  时间:2021-08-02  阅读:()

'getsockopt' : cannot convert parameter 5 from 'int' to 'int *' 请问怎么修改啊???

将代码:if(getsockopt (sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&,optlen)==SOCKET_ERROR) 改成:if(getsockopt (sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&,&optlen)==SOCKET_ERROR) 就可以了,因为该函数的原型为: int getsockopt ( SOCKET s, int level, int optname, char FAR* al, int FAR* optlen ); 要求最后一个参数必须是指针

如何设置connect超时时间

1.首先将标志位设为Non-blocking模式,准备在非阻塞模式下调用connect函数 2.调用connect,正常情况下,因为TCP三次握手需要一些时间;而非阻塞调用只要不能立即完成就会返回错误,所以这里会返回EINPROGRESS,表示在建立连接但还没有完成。

3.在读套接口描述符集(fd_set rset)和写套接口描述符集(fd_set wset)中将当前套接口置位(用FD_ZERO()、FD_SET()宏),并设置好超时时间(struct timeval *timeout) 4.调用select( socket, &rset, &wset, NULL, timeout ) 返回0表示connect超时 如果你设置的超时时间大于75秒就没有必要这样做了,因为内核中对connect有超时限制就是75秒。

网络编程中socket的分量我想大家都很清楚了,socket也就是套接口,在套接口编程中,提到超时的概念,我们一下子就能想到3个:发送超时,接收超时,以及select超时(注: select 函数并不是只用于套接口的,但是套接口编程中用的比较多),在connect到目标主机的时候,这个超时是不由我们来设置的。

不过正常情况下这个超时都很 长,并且connect又是一个阻塞方法,一个主机不能连接,等着connect返回还能忍受,你的程序要是要试图连接多个主机,恐怕遇到多个不能连接的 主机的时候,会塞得你受不了的。

我也废话少说,先说说我的方法,如果你觉得你已掌握这种方法,你就不用再看下去了,如果你还不了解,我愿意与你分享。

本文 是已在Linux下的程序为例子,不过拿到Windows中方法也是一样,无非是换几个函数名字罢了。

Linux中要给connect设置超时,应该是有两种方法的。

一种是该系统的一些参数,这个方法我不讲,因为我讲不清楚:P,它也不是编程实现的。

另外一种方法就是变相的实现connect的超时,我要讲的就是这个方法,原理上是这样的: 1.建立socket 2.将该socket设置为非阻塞模式 3.调用connect() 4.使用select()检查该socket描述符是否可写(注意,是可写) 5.根据select()返回的结果判断connect()结果 6.将socket设置为阻塞模式(如果你的程序不需要用阻塞模式的,这步就省了,不过一般情况下都是用阻塞模式的,这样也容易管理) 如果你对网络编程很熟悉的话,其实我一说出这个过程你就知道怎么写你的程序了,下面给出我写的一段程序,仅供参考。

/****************************** * Time out for connect() * Write by Kerl W ******************************/ #include #include #define TIME_OUT_TIME 20 //connect超时时间20秒 int main(int argc , char **argv) { ……………… int sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd < 0) exit(1); struct sockaddr_in serv_addr; ………//以服务器地址填充结构serv_addr int error=-1, len; len = sizeof(int); timeval tm; fd_set set; unsigned long ul = 1; ioctl(sockfd, FIONBIO, &ul); //设置为非阻塞模式 bool ret = false; if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) { _set = TIME_OUT_TIME; _uset = 0; FD_ZERO(&set); FD_SET(sockfd, &set); if( select(sockfd+1, NULL, &set, NULL, &tm) > 0) { getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len); if(error == 0) ret = true; else ret = false; } else ret = false; } else ret = true; ul = 0; ioctl(sockfd, FIONBIO, &ul); //设置为阻塞模式 if(!ret) { close( sockfd ); fprintf(stderr , "Cannot Connect the server!n"); return; } fprintf( stderr , "Connected!n"); //下面还可以进行发包收包操作 …………… } 以上代码片段,仅供参考,也是为初学者提供一些提示,主要用到的几个函数,select, ioctl, getsockopt都可以找到相关资料,具体用法我这里就不赘述了,你只需要在linux中轻轻的敲一个man <函数名>就能够看到它的用法。

此外我需要说明的几点是,虽然我们用ioctl把套接口设置为非阻塞模式,不过select本身是阻塞的,阻塞的时间就是其超时的时间由调用select 的 时候的最后一个参数timeval类型的变量指针指向的timeval结构变量来决定的,timeval结构由一个表示秒数的和一个表示微秒数(long 类型)的成员组成,一般我们设置了秒数就行了,把微妙数设为0(注:1秒等于100万微秒)。

而select函数另一个值得一提的参数就是上面我们用到的 fd_set类型的变量指针。

调用之前,这个变量里面存了要用select来检查的描述符,调用之后,针对上面的程序这里面是可写的描述符,我们可以用宏 FD_ISSET来检查某个描述符是否在其中。

由于我这里只有一个套接口描述符,我就没有使用FD_ISSET宏来检查调用select之后这个 sockfd是否在set里面,其实是需要加上这个判断的。

不过我用了getsockopt来检查,这样才可以判断出这个套接口是否是真的连接上了,因为 我们只是变相的用select来检查它是否连接上了,实际上select检查的是它是否可写,而对于可写,是针对以下三种条件任一条件满足时都表示可写 的: 1)套接口发送缓冲区中的可用控件字节数大于等于套接口发送缓冲区低潮限度的当前值,且或者i)套接口已连接,或者ii)套接口不要求连接(UDP方式的) 2)连接的写这一半关闭。

3)有一个套接口错误待处理。

这样,我们就需要用getsockopt函数来获取套接口目前的一些信息来判断是否真的是连接上了,没有连接上的时候还能给出发生了什么错误,当然我程序中并没有标出那么多状态,只是简单的表示可连接/不可连接。

下面我来谈谈对这个程序测试的结果。

我针对3种情形做了测试: 1. 目标机器网络正常的情况 可以连接到目标主机,并能成功以阻塞方式进行发包收包作业。

2. 目标机器网络断开的情况 在等待设置的超时时间(上面的程序中为20秒)后,显示目标主机不能连接。

3. 程序运行前断开目标机器网络,超时时间内,恢复目标机器的网络 在恢复目标主机网络连接之前,程序一只等待,恢复目标主机后,程序显示连接目标主机成功,并能成功以阻塞方式进行发包收包作业。

以 上各种情况的测试结果表明,这种设置connect超时的方法是完全可行的。

我自己是把这种设置了超时的connect封装到了自己的类库,用在一套监控 系统中,到目前为止,运行还算正常。

这种编程实现的connect超时比起修改系统参数的那种方法的有点就在于它只用于你的程序之中而不影响系统。

connect非阻塞套接口时候,一般使用在以下几种情况: 1.三路握手需要时间,这个要视具体的网络情况而定。

当然也有可能失败。

在三路握手的时候我们并不需要在原地等待三路握手的完成,可以用这些时间来 完成其它事情,然后当这些事情完成后,再去检测连接是否建立(也就是三路握手是否完成)。

2.可以用这种技术来同时建立多个连接。

(WEB浏览器中很常用)。

3.connect超时需要很长时间才会通知,如果我们认为超过0.1秒以后就算超时(不管它是不是真的超时),这是就可以使用非阻塞式I/O结合 select来完成。

当采用非阻塞式I/O来使用connect时候,要判断一个连接是否建立则比较复杂,需要按照以下几个步骤来完成 1.即使是使用非阻塞式的connect操作,connect依然可能正确返回,也就是说非阻塞的connect 也有可能三路连接完成后返回,这种情况一般发生在服务器和主机在同一个机器上,所以第一步要判断connect是否正确返回,如果正确返回则请做正确返回 的处理,否则进入步骤2 2.设置fd_set,(如果没看明白,请先看select函数介绍),让select函数同时监听套接字的读写2个属性,如果既可读也可写则进入 步骤3,如果可写但不可读进入步骤4. 3.如果到达这步,我们需要调用getsockopt进一步判断。

这里涉及到一个移植问题,getsockopt如果发生错误, 源自Berkeley的实现会返回0,如果是solaris,则会返回-1。

建议是2个都处理(如果看不明白请先看getsockopt函数,套接口选 项)。

根据getsockopt通过参数返回的erron的值,如果值为0则表示链接建立完成,如果不为0, 则说明链接建立没有完成。

4.如果能到达这里,则说明连接建立完成。

最后,即使最后你得出链接没有建立完成,也只是说:可能三路握手的过程还是没有完成。

如何判断socket已经断开

可以根据recv和send的返回值判断,也可以用getsockopt判断: ?getsockopt(sock,?IPPROTO_TCP,?TCP_INFO,?&info,?(socklen_t?*)?&?len); ?if?((info.tcpi_state?==?TCP_ESTABLISHED))?{ ????/*?Connected?*/ }? ?else ??{ ????/*?Disconnected?*/ }

LOCVPS洛杉矶CN2线路KVM上线,洛杉矶/香港云地/香港邦联7折

LOCVPS发来了新的洛杉矶CN2线路主机上线通知,基于KVM架构,目前可与香港云地、香港邦联机房XEN架构主机一起适用7折优惠码,优惠后最低美国洛杉矶CN2线路KVM架构2GB内存套餐月付38.5元起。LOCPVS是一家成立较早的国人VPS服务商,目前提供洛杉矶MC、洛杉矶C3、和香港邦联、香港沙田电信、香港大埔、日本东京、日本大阪、新加坡、德国和荷兰等机房VPS主机,基于KVM或者XEN架构。...

BlueHost 周年庆典 - 美国/香港虚拟主机 美国SSD VPS低至月32元

我们对于BlueHost主机商还是比较熟悉的,早年我们还是全民使用虚拟主机的时候,大部分的外贸主机都会用到BlueHost无限虚拟主机方案,那时候他们商家只有一款虚拟主机方案。目前,商家国际款和国内款是有差异营销的,BlueHost国内有提供香港、美国、印度和欧洲机房。包括有提供虚拟主机、VPS和独立服务器。现在,BlueHost 商家周年活动,全场五折优惠。我们看看这次的活动有哪些值得选择的。 ...

什么是BGP国际线路及BGP线路有哪些优势

我们在选择虚拟主机和云服务器的时候,是不是经常有看到有的线路是BGP线路,比如前几天有看到服务商有国际BGP线路和国内BGP线路。这个BGP线路和其他服务线路有什么不同呢?所谓的BGP线路机房,就是在不同的运营商之间通过技术手段时间各个网络的兼容速度最佳,但是IP地址还是一个。正常情况下,我们看到的某个服务商提供的IP地址,在电信和联通移动速度是不同的,有的电信速度不错,有的是移动速度好。但是如果...

getsockopt为你推荐
enhancedenhance 的名词是什么注册表命令运行注册表命令是什么?hd4600ati radeon hd 4600 这显卡好不好 多少钱seasonalholiday 和weekend seasonal activities 有什么区别word打字后面的字消失word中打字后面的一个字就不见了是什么原因啊?高手指教下,谢谢!!!!!appmakr国外的appmakr和国内的apicloud有什么区别?boltzmann波尔兹曼常数的值是多少逗号运算符c语言的逗号运算符什么意思,举例解释下订单详情在淘宝上买东西,显示订单已发货,但是没有订单详情。可能有几种原因?scanf返回值scanf的返回值
万网域名代理 最便宜的vps 山东vps 132邮箱 cve-2014-6271 uk2 lamp配置 java虚拟主机 老左来了 香港新世界中心 七夕快乐英语 双12 台湾google 网站加速软件 成都主机托管 免费稳定空间 学生机 windowssever2008 linux服务器系统 ubuntu安装教程 更多