读书人

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

发布时间: 2012-01-16 23:36:51 作者: rapoo

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的参数就应该是代理的地址和端口,同时你要处理与代理的交互,

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

读书人网 >VC/MFC

热点推荐