首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

FTP数据连接连接远程服务器时超时,该如何处理

2012-01-16 
FTP数据连接连接远程服务器时超时我碰到的问题是这样的:我用SOCKET来做一个FTP上传/下载.控制连接和数据连

FTP数据连接连接远程服务器时超时
我碰到的问题是这样的:
我用SOCKET来做一个FTP上传/下载.控制连接和数据连接在本机和局域网能都能连接上,但连接到远程FTP服务器时就连不上了.connect的时候阻塞和非阻塞方式我都试过了,出现的错误都是是10060:连接超时.请问这是什么原因引起的?怎么样才能解决?除了防火墙的因素外还有什么其他问题会导致这样?   我第一次提问,我分数不多,请高手帮帮忙,谢了.相关的代码见下:

UINT   CFtp::ListFunc(LPVOID   param)
{
          .....
          QueueFtpCmd(pListInfo-> m_hCtrlSock, "PASV ");//pasv传输方式
          retFlag=GetReply(pListInfo-> m_hCtrlSock, "227 ",revStr);//获取FTP响应
          if(!retFlag)
          {
                  return   EXIT_ERROR;
            }
          CString   strHost   =   GetHost(revStr);//得到远程服务器地址
          int   nPort   =   GetPort(revStr);//得到远程服务器数据端口
          hDataSock   =   GetConnect(strHost,nPort);//得到数据连接,函数见下面
          if(hDataSock   ==   INVALID_SOCKET)  
          {
//错误:无法建立数据连接
            }

            QueueFtpCmd(pListInfo-> m_hCtrlSock, "LIST ");
            retFlag=GetReply(pListInfo-> m_hCtrlSock, "150 ",revStr);
            ......
            return   EXIT_SUCCESS;
}

//控制连接和数据连接都有这个函数来连远程服务器    
SOCKET   CFtp::GetConnect(CString   host   ,int   port)
{
        SOCKET   hSocket;
        SOCKADDR_IN   saServer;                     //   服务器套接字地址.

        //   创建一个绑定到服务器的TCP/IP套接字.
        if   ((hSocket   =   socket   (PF_INET,   SOCK_STREAM,   0)==INVALID_SOCKET)
        {
TRACE( "Allocating   socket   failed.   Error:   %d\n ",WSAGetLastError   ());
return   INVALID_SOCKET;
        }


        saServer.sin_family   =   AF_INET;//   使用TCP/IP协议.
        saServer.sin_port   =   htons   (port);//   设定套接字端口号.
        saServer.sin_addr.S_un.S_addr   =   inet_addr(host);//转换成网络使用的二进制数字
        memset(saServer.sin_zero,0,8);

        //   就是在这里出现问题:   总出现超时  
        if   (connect   (hSocket,(PSOCKADDR)   &saServer,   sizeof   (saServer))   ==   SOCKET_ERROR)  
      {
TRACE( "Connecting   to   the   server   failed.   Error:   %d\n ",WSAGetLastError   ());
if(WSAGetLastError   ()==10060)
{
}
closesocket   (hSocket);
return   INVALID_SOCKET;
          }

        return   hSocket;
}

//这个函数是我尝试用非阻塞方式来连接的
SOCKET   CFtp::GetConnect(CString   host   ,int   port)
{
        SOCKET   hSocket;
SOCKADDR_IN   saServer;                     //   服务器套接字地址.



//   创建一个绑定到服务器的TCP/IP套接字.
if   ((hSocket   =   socket   (PF_INET,   SOCK_STREAM,   0))   ==   INVALID_SOCKET)
{
TRACE( "Allocating   socket   failed.   Error:   %d\n ",WSAGetLastError   ());
return   INVALID_SOCKET;
}


saServer.sin_family   =   AF_INET;//   使用TCP/IP协议.
saServer.sin_port   =   htons   (port);//   设定套接字端口号.
saServer.sin_addr.S_un.S_addr   =   inet_addr(host);//转换成网络使用的二进制数字
memset(saServer.sin_zero,0,8);

unsigned   long   ul=1;
int   ret=ioctlsocket(hSocket,FIONBIO,&ul);//设置为非阻塞模式
if(ret==SOCKET_ERROR)
{
return   INVALID_SOCKET;
}

//   建立到服务器的套接字连接.
if   (connect   (hSocket,(PSOCKADDR)   &saServer,   sizeof   (saServer))   ==   SOCKET_ERROR)  
{
afxDump < < "连接错误: " < <WSAGetLastError() < < "\n ";
if(WSAGetLastError()==WSAEWOULDBLOCK)
{
            fd_set   wd;
            FD_ZERO(&wd);
            FD_SET(hSocket,&wd);
          struct   timeval   timeout;
          timeout.tv_sec=10;//10秒
          timeout.tv_usec=0;
          ret=select(0,0,&wd,0,&timeout);
        if(ret==SOCKET_ERROR)
        {
closesocket(hSocket);
afxDump < < "select= " < <WSAGetLastError() < < "\n ";
return   INVALID_SOCKET;
        }else
        if(ret==0)//超时发生
        {
afxDump < < "timeout= " < <WSAGetLastError() < < "\n ";
return   INVALID_SOCKET;
        }
      else
      {
unsigned   long   ul1=0;
ret=ioctlsocket(hSocket,FIONBIO,&ul1);//改为阻塞模式
if(ret==SOCKET_ERROR)
{
        closesocket(hSocket);
        return   INVALID_SOCKET;
}
                                      return   hSocket;
}

            }//end   of   if
      }

      return   INVALID_SOCKET;
}

[解决办法]
你是通过什么方式访问外网的,如果是代理的话是不行的
[解决办法]
用代理的话,connect的参数就应该是代理的地址和端口,同时你要处理与代理的交互,

如果你不这样做,就永远是直连外网,你可以成功,说明并不是不能直连,但是成功率就很低很低了

热点排行