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;
}