FTP数据连接连接远程服务器时超时

jacky_gxc 2007-07-03 02:30:20
我碰到的问题是这样的:
我用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;
}
...全文
1134 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
jacky_gxc 2007-07-16
  • 打赏
  • 举报
回复
结了,我已经解决了,谢谢!
xujianlane 2007-07-04
  • 打赏
  • 举报
回复
你是通过什么方式访问外网的,如果是代理的话是不行的
jacky_gxc 2007-07-04
  • 打赏
  • 举报
回复
自己顶起来,别沉了
很急的,各位大哥帮帮忙
jacky_gxc 2007-07-04
  • 打赏
  • 举报
回复
那是不是说我和代理交互的话
CONNECT先连代理得到响应后再连外网服务器.
还有 为什么用了代理还能直连,这是个什么情况?
sealy_2007 2007-07-04
  • 打赏
  • 举报
回复
用代理的话,connect的参数就应该是代理的地址和端口,同时你要处理与代理的交互,

如果你不这样做,就永远是直连外网,你可以成功,说明并不是不能直连,但是成功率就很低很低了
jacky_gxc 2007-07-04
  • 打赏
  • 举报
回复
是通过代理访问的
但之前用阻塞方式在调试状态下数据连接能成功
但成功的次数很少
这一点我也很疑惑

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧