【发布时间】:2014-10-17 12:12:32
【问题描述】:
我尝试制作一个以活动模式上传文件的 FTP 客户端(C++ 与 linux 的套接字库)。 当我想在本地服务器(LAN)上发送文件时,我的程序可以工作,但它 当我想在远程服务器(WAN)上发送文件时不起作用。 我有错误 425 无法打开数据连接。我做了很多研究 通常这个问题来自 NAT(它可能被阻止 数据连接端口)。但我已经尝试使用 Filezilla(处于活动模式)并且它有效。 所以我没找到数据连接的问题在哪里。
这是我的代码:
using namespace std;
int sock;
int sock_data,new_sock;
struct sockaddr_in sin_data;
struct sockaddr_in cli_addr = {0};
char* receiving(int socket)
{
char message[1000] = {'/0'};
recv(socket,message,sizeof(message),0);
cout << message << endl;
return message;
}
void *send_data(void* args)
{
send(sock,"STOR fichier.txt\r\n",sizeof("STOR fichier.txt\r\n"),0);
receiving(sock);
return(0);
}
void *accept_data_connexion(void* args)
{
sock_data = socket(AF_INET,SOCK_STREAM,6);
sin_data.sin_family = AF_INET;
sin_data.sin_port = htons(58703);
sin_data.sin_addr.s_addr = INADDR_ANY;
socklen_t clilen = sizeof(cli_addr);
new_sock = accept(sock_data,(struct sockaddr *)&cli_addr,&clilen);
if(errno == 0)
{
cout << "Data connection is established" << endl;
}
}
int main()
{
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(21);
sin.sin_addr.s_addr = inet_addr("xxx,xxx,xxx,xxx");
sock = socket(AF_INET,SOCK_STREAM,6);
//connection
connect(sock,(struct sockaddr *)&sin,sizeof(sin));
receiving(sock);
receiving(sock);
print_box();
//log in
send(sock,"USER username\r\n",sizeof("USER username\r\n"),0);
receiving(sock);
send(sock,"PASS password\r\n",sizeof("PASS password\r\n"),0);
receiving(sock);
send(sock,"SYST\r\n",sizeof("SYST\r\n"),0);
receiving(sock);
send(sock,"PWD\r\n",sizeof("PWD\r\n"),0);
receiving(sock);
send(sock,"PORT xxx,xxx,xxx,xxx,229,79",sizeof("PORT xxx,xxx,xxx,xxx,229,79"),0);
receiving(sock);
send(sock,"TYPE I \r\n",sizeof("TYPE I \r\n"),0);
receiving(sock);
pthread_t th1, th2;
void *ret;
pthread_create (&th1,NULL, accept_data_connexion,(void*)1);
pthread_create (&th2, NULL, send_data,(void *)2);
(void)pthread_join (th1, &ret);
(void)pthread_join (th2, &ret);
ifstream fichier("fichier.txt");
int i = 0;
while(fichier.eof() == false)
{
fichier.seekg(i,fichier.beg);
char* buffer= new char[1];
fichier.read(buffer,1);
write(new_sock,buffer,1);
i++;
}
fichier.close();
close(new_sock);
close(sock_data);
close(sock);
return 0;
}
【问题讨论】:
-
您可以使用wireshark等流量捕获工具来查看其他客户端向服务器发送的命令。