socket连接超时问题_socket error or timeout!-程序员宅基地

技术标签: struct  server  网络  stream  编程  socket  

一部分  

      把CSDN与中文yahoo翻了底朝天,也没找到如何设置socket的连接超时的满意方法,问此问题的兄弟已有一大堆,这里偶就讲一下win下如何设置socket的connect超时。
设置connect的超时很简单,CSDN上也有人提到过使用select,但却没有一个令人满意与完整的答案。偶所讲的也正是select函数,此函数集成在winsock1.1中,简单点讲,"作用使那些想避免在套接字调用过程中被锁定的应用程序,采取一种有序的方式,同时对多个套接字进行管理"(《Windows网络编程技术》原话)。使用方法与解释请见《Windows网络编程技术》。
在使用此函数前,需先将socket设置为非锁定模式,这样,在connect时,才会立马跳过,同时,通常也会产生一个WSAEWOULDBLOCK错误,这个错误没关系。再执行select则是真正的超时。

WSADATA wsd;
SOCKET cClient;
int ret;
struct sockaddr_in server;
hostent *host=NULL;

if(WSAStartup(MAKEWORD(2,0),&wsd)){return 0;}
cClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(cClient==INVALID_SOCKET){return 0;}
//set Recv and Send time out
int TimeOut=6000; //设置发送超时6秒
if(::setsockopt(cClient,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR){
return 0;
}
TimeOut=6000;//设置接收超时6秒
if(::setsockopt(cClient,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR){
return 0;
}
//设置非阻塞方式连接
unsigned long ul = 1;
ret = ioctlsocket(cClient, FIONBIO, (unsigned long*)&ul);
if(ret==SOCKET_ERROR)return 0;

//连接
server.sin_family = AF_INET;
server.sin_port = htons(25);
server.sin_addr .s_addr = inet_addr((LPCSTR)pSmtp);
if(server.sin_addr.s_addr == INADDR_NONE){return 0;}

connect(cClient,(const struct sockaddr *)&server,sizeof(server));

//select 模型,即设置超时
struct timeval timeout ;
fd_set r;

FD_ZERO(&r);
FD_SET(cClient, &r);
timeout.tv_sec = 15; //连接超时15秒
timeout.tv_usec =0;
ret = select(0, 0, &r, 0, &timeout);
if ( ret <= 0 )
{
::closesocket(cClient);
return 0;
}
//一般非锁定模式套接比较难控制,可以根据实际情况考虑 再设回阻塞模式
unsigned long ul1= 0 ;
ret = ioctlsocket(cClient, FIONBIO, (unsigned long*)&ul1);
if(ret==SOCKET_ERROR){
::closesocket (cClient);
return 0;
}

 

--------------------------------------------------------------------------------------------------------------

LINUX下的方法:

 

在阻塞套接字的一般情况下,connect ()直到客户端对SYN消息的ACK消息到达之前才会返回。使connect()调用具有超时机制的一个方法是让套接字成为非阻塞的套接字体,然后用select()来等待它完成。
[code:1:7901c37cf2]
s = socket(AF_INET, SOCK_STREAM, 0);
//下面获取套接字的标志
if ((flags = fcntl(s, F_GETFL, 0)) < 0) {
    //错误处理
}

//下面设置套接字为非阻塞
if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
    //错误处理
}

if ((retcode = connect(s, (struct sockaddr*)&peer, sizeof(peer)) && 
    errno != EINPROGRESS) {
   //因为套接字设为NONBLOCK,通常情况下,连接在connect()返回
   //之前是不会建立的,因此它会返回EINPROGRESS错误,如果返回
   //任何其他错误,则要进行错误处理
}

if (0 == retcode) {  //如果connect()返回0则连接已建立
    //下面恢复套接字阻塞状态
    if (fcntl(s, F_SETFL, flags) < 0) {
        //错误处理
    }

    //下面是连接成功后要执行的代码
    
    exit(0)
}

FD_ZERO(&rdevents);
FD_SET(s, &rdevents);  //把先前的套接字加到读集合里面
wrevents = rdevents;   //写集合
exevents = rdevents;   //异常集合

tv.tv_sec = 5;  //设置时间为5秒
tv_tv_usec = 0;

retcode = select(s+1, &rdevents, &wrevents, &exevents, &tv);
if (retcode < 0) {  //select返回错误???
    //错误处理
}
else if (0 == retcode) {  //select 超时???
    //超时处理
}
esle {
    //套接字已经准备好
    if (!FD_ISSET(s, &rdevents) && !FD_ISSET(s, &wrevents)) {
        //connect()失败,进行错处理
    }

    if (getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
        //getsockopt()失败,进行错处理
    }

    if (err != 0) {
        //connect()失败,进行错处理
    }

    //到这里说明connect()正确返回
    //下面恢复套接字阻塞状态
    if (fcntl(s, F_SETFL, flags) < 0) {
        //错误处理
    }

    //下面是连接成功后要执行的代码
    
    exit(0)

二部分

 

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秒。


[From]http://www.ycgczj.com.cn/34733.html
网络编程中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 <sys/socket.h>
#include <sys/types.h>
#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)
   {
     tm.tv_set  = TIME_OUT_TIME;
     tm.tv_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 超时,socket connect,socket 超时,socket连接超时设置,connect,mysql connect,connect by,connect by prior,connect player,media connect


关于c/s 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;


}
 

 
 
 
setsockopt函数解析(转) - [IT]{#timeline}
Tag:IT
int setsockopt (
  SOCKET s,                
  int level,               
  int optname,             
  const char FAR * optval, 
  int optlen               
);

The Windows Sockets setsockopt function sets a socket option.

中文解释好像是:设置套接字的选项。

先看如下代码:
setsockopt(SockRaw,IPPROTO_IP,IP_HDRINCL,(char *)&flag,sizeof(int))

这里是设置SockRaw这个套接字的ip选项中的IP_HDRINCL

参考以下资料:

***************************************************************************************************

Linux网络编程--8. 套接字选项
有时候我们要控制套接字的行为(如修改缓冲区的大小),这个时候我们就要控制套接字的选项了. 

8.1 getsockopt和setsockopt 
int getsockopt(int sockfd,int level,int optname,void *optval,socklen_t *optlen)
int setsockopt(int sockfd,int level,int optname,const void *optval,socklen_t *optlen)
level指定控制套接字的层次.可以取三种值:
1)SOL_SOCKET:通用套接字选项.
2)IPPROTO_IP:IP选项.
3)IPPROTO_TCP:TCP选项. 
optname指定控制的方式(选项的名称),我们下面详细解释 
optval获得或者是设置套接字选项.根据选项名称的数据类型进行转换 

选项名称        说明                  数据类型
========================================================================
            SOL_SOCKET
------------------------------------------------------------------------
SO_BROADCAST      允许发送广播数据            int
SO_DEBUG        允许调试                int
SO_DONTROUTE      不查找路由               int
SO_ERROR        获得套接字错误             int
SO_KEEPALIVE      保持连接                int
SO_LINGER        延迟关闭连接              struct linger
SO_OOBINLINE      带外数据放入正常数据流         int
SO_RCVBUF        接收缓冲区大小             int
SO_SNDBUF        发送缓冲区大小             int
SO_RCVLOWAT       接收缓冲区下限             int
SO_SNDLOWAT       发送缓冲区下限             int
SO_RCVTIMEO       接收超时                struct timeval
SO_SNDTIMEO       发送超时                struct timeval
SO_REUSERADDR      允许重用本地地址和端口         int
SO_TYPE         获得套接字类型             int
SO_BSDCOMPAT      与BSD系统兼容              int
==========================================================================
            IPPROTO_IP
--------------------------------------------------------------------------
IP_HDRINCL       在数据包中包含IP首部          int
IP_OPTINOS       IP首部选项               int
IP_TOS         服务类型
IP_TTL         生存时间                int
==========================================================================
            IPPRO_TCP
--------------------------------------------------------------------------
TCP_MAXSEG       TCP最大数据段的大小           int
TCP_NODELAY       不使用Nagle算法             int
=========================================================================
关于这些选项的详细情况请查看 Linux Programmer"s Manual 
8.2 ioctl 
ioctl可以控制所有的文件描述符的情况,这里介绍一下控制套接字的选项. 
int ioctl(int fd,int req,...)
 
==========================================================================
            ioctl的控制选项
--------------------------------------------------------------------------
SIOCATMARK       是否到达带外标记            int
FIOASYNC        异步输入/输出标志            int
FIONREAD        缓冲区可读的字节数           int
==========================================================================
详细的选项请用 man ioctl_list 查看. 

 


Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=588497
 
1.closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket:
BOOL bReuseaddr=TRUE;
setsockopt(s,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(BOOL));
2. 如果要已经处于连接状态的soket在调用closesocket后强制关闭,不经历
TIME_WAIT的过程:
BOOL bDontLinger = FALSE;
setsockopt(s,SOL_SOCKET,SO_DONTLINGER,(const char*)&bDontLinger,sizeof(BOOL));
3.在send(),recv()过程中有时由于网络状况等原因,发收不能预期进行,而设置收发时限:
int nNetTimeout=1000;//1秒
//发送时限
setsockopt(socket,SOL_S0CKET,SO_SNDTIMEO,(char *)&nNetTimeout,sizeof(int));
//接收时限
setsockopt(socket,SOL_S0CKET,SO_RCVTIMEO,(char *)&nNetTimeout,sizeof(int));
4.在send()的时候,返回的是实际发送出去的字节(同步)或发送到socket缓冲区的字节
(异步);系统默认的状态发送和接收一次为8688字节(约为8.5K);在实际的过程中发送数据
和接收数据量比较大,可以设置socket缓冲区,而避免了send(),recv()不断的循环收发:
// 接收缓冲区
int nRecvBuf=32*1024;//设置为32K
setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
//发送缓冲区
int nSendBuf=32*1024;//设置为32K
setsockopt(s,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
5. 如果在发送数据的时,希望不经历由系统缓冲区到socket缓冲区的拷贝而影响
程序的性能:
int nZero=0;
setsockopt(socket,SOL_S0CKET,SO_SNDBUF,(char *)&nZero,sizeof(nZero));
6.同上在recv()完成上述功能(默认情况是将socket缓冲区的内容拷贝到系统缓冲区):
int nZero=0;
setsockopt(socket,SOL_S0CKET,SO_RCVBUF,(char *)&nZero,sizeof(int));
7.一般在发送UDP数据报的时候,希望该socket发送的数据具有广播特性:
BOOL bBroadcast=TRUE;
setsockopt(s,SOL_SOCKET,SO_BROADCAST,(const char*)&bBroadcast,sizeof(BOOL));
8.在client连接服务器过程中,如果处于非阻塞模式下的socket在connect()的过程中可
以设置connect()延时,直到accpet()被呼叫(本函数设置只有在非阻塞的过程中有显著的
作用,在阻塞的函数调用中作用不大)
BOOL bConditionalAccept=TRUE;
setsockopt(s,SOL_SOCKET,SO_CONDITIONAL_ACCEPT,(const char*)&bConditionalAccept,sizeof(BOOL));
9.如果在发送数据的过程中(send()没有完成,还有数据没发送)而调用了closesocket(),以前我们
一般采取的措施是"从容关闭"shutdown(s,SD_BOTH),但是数据是肯定丢失了,如何设置让程序满足具体
应用的要求(即让没发完的数据发送出去后在关闭socket)?
struct linger {
u_short l_onoff;
u_short l_linger;
};
linger m_sLinger;
m_sLinger.l_onoff=1;//(在closesocket()调用,但是还有数据没发送完毕的时候容许逗留)
// 如果m_sLinger.l_onoff=0;则功能和2.)作用相同;
m_sLinger.l_linger=5;//(容许逗留的时间为5秒)
setsockopt(s,SOL_SOCKET,SO_LINGER,(const char*)&m_sLinger,sizeof(linger));


本文来自程序员宅基地,转载请标明出处:http://blog.csdn.net/chenguangf/archive/2008/02/19/2107302.aspx

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/WINCOL/article/details/6158774

智能推荐

炫酷!200 行 Python 代码实现马赛克拼图!_图片转换马赛克拼图-程序员宅基地

文章浏览阅读715次。在一图胜千言的时代,没有什么比一张图片更有冲击力的了,那如果一千张图片拼接起来是什么效果呢?别问,问就是两字 —— 炫酷!你有没有想过上面的图片是怎么实现的,难道这是用 ps 一张张拼起来的?当然,靠人工把近千张图片按照色域一一排列,应该是不可能的。今天我们就用 Python 做一个马赛克图片生成器~ 只需要 200 行 Python 代码,就可以将任意图片转化为马赛克拼图效果,一劳永逸!拿来记录校园生活、游戏生涯、送女朋友都最合适不过了!ONE项目思路项目大概_图片转换马赛克拼图

改善深层神经网络(5) —— 超参数调试,Batch正则化和程序框架_超参数间存在耦合-程序员宅基地

文章浏览阅读285次。文章目录1. 调试处理2.为参数选择合适的范围2.12.2 从粗略到精确的选择2.3 如何使用合理的范围1. 调试处理首先,我们先列举部分我们常见的超参数:学习率α动量梯度下降因子βAdam算法的三个超参数β1,β2,εβ_1,β_2,εβ1​,β2​,ε2.为参数选择合适的范围2.12.2 从粗略到精确的选择2.3 如何使用合理的范围..._超参数间存在耦合

ORB-SLAM3笔记_orb_slam3替换相机模型-程序员宅基地

文章浏览阅读725次,点赞3次,收藏2次。相对orbslam2的改进点有: IMU的官方支持 引入相机通用类,方便替换不同模型的相机。并且官方实现了通用相机模型,就是pinhole-equi或者fisheye模型。 假如地图管理功能,支持多个子地图的存在,以及可能的时候合并子地图 recall更高的回环检测,因为要合并地图。如果recall太低,会照成大量的重复地图。 之前的做法是要求DBOW能够找到连续的3 frame。现在改为只要找到1 frame,然后就做集合一致性检查。 使用通用相机模型带来的改变 因为非小孔_orb_slam3替换相机模型

如何获取每月第一个/最后一个交易日_获取每个月第一个交易日sql语句-程序员宅基地

文章浏览阅读5k次,点赞4次,收藏7次。思路是,获取指数的行情信息,然后利用如下代码进行判断:data['first'] = data['trade_date'].where(data['month'] != data.shift(1)['month'], np.nan)data['last'] = data['trade_date'].where(data['month'] != data.shift(-1)['month'], np.nan)完整代码如下:数据源我用的是wind,大家可以用tushare来替代,获取更简单一些._获取每个月第一个交易日sql语句

iso文件:抱歉,装载文件时出现问题_抱歉,装载文件时出现问题-程序员宅基地

文章浏览阅读2.4w次,点赞3次,收藏7次。问题描述右击 ISO 文件选择“装载”,便会弹出一个消息框报错,这该怎么办呢? 解决方法网上有很多的解决办法,例如:更改驱动器号和路径或者是更改注册表 但是我感觉应该没有那么多问题,继续在网上找解决的方法,终于找到一个简单的方法,具体方法如下: 1.右键点属性 2.详细信息 一般不能装载的都是属性都是RAP,可以装载的是RA 3.选择删除属性和个人信息 4.接下来会生成一个副本_抱歉,装载文件时出现问题

在VMware15中创建虚拟机安装ubuntu系统(超详细教程)_vmware15可以装ubuntu14.04-程序员宅基地

文章浏览阅读1.2w次,点赞13次,收藏103次。此篇博文分享幼儿园老小(本人)创建虚拟机安装ubuntu系统的详细操作过程,希望对新手有所帮助咯!(大佬请自行略过哈哈)我的下载地址详情如下:下载请戳–>Ubuntu18.04/64位下载地址提取码:fv6h操作详细过程:1、选中下载完成的ubuntu.rar压缩包,右键选择解压,路径自己选择,我这里是直接【解压到ubuntu】,等待解压完成。2、点击解压完的【ubuntu文件..._vmware15可以装ubuntu14.04

随便推点

Tree树状图的动态增删查改(中)新增节点_kd tree 树 动态 增删 增加 删除 节点 调整-程序员宅基地

文章浏览阅读2.9k次。一、 新增节点1、 新增的基本功能样式可以在tree里面的案例找到,我这里用的添加节点是子节点,父节点其实是不用插件里面那个添加的。只要配置合适,给子节点添加子节点,该节点就会自动变成父节点的,前提是取消节点锁定。2、下面三个a标签分别是添加、修改和删除,把id等值写对了就能对树进行编辑操作了。3、 只要上面的HTML样式写对了,点击了a标签它插件就会自己调用下面的add方法,新增节点后..._kd tree 树 动态 增删 增加 删除 节点 调整

你不知道的功力非凡的20个windows XP小秘密_你所不知道的xp-程序员宅基地

文章浏览阅读745次。你不知道的功力非凡的20个windows XP小秘密 1. systeminfo:让XP列出更多有用信息 Windows XP 总是在炫耀它可以给稳定工作多么长的时间!要想详细地了解这一信息,你可以接入 Windows的“开始菜单”,再开启“附件菜单”中的“命令提示符”,然后在其中输入“systeminfo”这个命令。电脑就会给你显示出许多有用信息,其中包括了这个系统的初次安装时间,以及本次持_你所不知道的xp

nginx常用模块功能介绍_htpasswd -cb-程序员宅基地

文章浏览阅读613次。实验环境:centos7.6,2G内存,50G硬盘大小,虚拟机ip:172.16.1.7,172.16.1.8,172.16.1.9nginx模块nginx访问模块:ngx_http_access_module目的:禁止外网访问,允许内网访问,我这里10.0.0.0是外网,172.16.1.0是内网1.举例配置: location / { deny 192.168.1.1; allow 192.168.1.0/24; allow 10.1.1.0/16; _htpasswd -cb

图论算法——图的遍历_洛谷 图的深度优先算法-程序员宅基地

文章浏览阅读5.2k次,点赞2次,收藏3次。图的基本应用——图的遍历,从具体的题目着手,学习图的遍历方式及代码形式。_洛谷 图的深度优先算法

mongo基础语句全解析_mongo语句-程序员宅基地

文章浏览阅读977次。MongoDB概念解析 SQL术语/概念 MongoDB术语/概念 解释/说明 database database 数据库 table collection 数据库表/集合 row documen..._mongo语句

Swift 编程语言入门教程_swift 入门教程 书籍-程序员宅基地

文章浏览阅读522次。原文地址:http://gashero.iteye.com/blog/2075324目录1 简介2 Swift入门3 简单值4 控制流5 函数与闭包6 对象与类7 枚举与结构1 简介今天凌晨Apple刚刚发布了Swift编程语言,本文从其发布的书籍《The Swift Programming Language》中摘录和_swift 入门教程 书籍

推荐文章

热门文章

相关标签