当我尝试使用ftp访问我的ls命令时,我总是在PORT部分命中425,有人可以告诉我为什么会这样吗?我的用户部分工作,如果我可以让端口工作,我可以专注于STOR和RETR。
/*FTP server*/
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/*for getting file size using stat()*/
#include<sys/stat.h>
/*for sendfile()*/
#include<sys/sendfile.h>
/*for O_RDONLY*/
#include<fcntl.h>
int active=0;
int sock1, sock2;
char buf[100], command[5], filename[20];
struct sockaddr_in remoteaddr, remoteaddr_data;
int main(int argc,char *argv[])
{
struct sockaddr_in server, client;
struct stat obj;
struct sockaddr_in local_data_addr_act;
int s, s_data, s_data_act;
s = socket(AF_INET, SOCK_STREAM, 0);
s_data = socket(AF_INET, SOCK_STREAM, 0);
s_data_act = socket(AF_INET, SOCK_STREAM, 0);
int k, i, size, len, c;
int filehandle;
sock1 = socket(AF_INET, SOCK_STREAM, 0);
if(sock1 == -1)
{
printf("Socket creation failed");
exit(1);
}
server.sin_port = htons(atoi(argv[1]));
server.sin_addr.s_addr = 0;
k = bind(sock1,(struct sockaddr*)&server,sizeof(server));
if(k == -1)
{
printf("Binding error");
exit(1);
}
k = listen(sock1,1);
if(k == -1)
{
printf("Listen failed");
exit(1);
}
len = sizeof(client);
sock2 = accept(sock1,(struct sockaddr*)&client, &len);
write(sock2,"220\r\n", 6);
i = 1;
while(1)
{
recv(sock2, buf, 100, 0);
printf("%s\n", buf);
sscanf(buf, "%s", command);
printf("%s\n", command);
if(!strcmp(command, "LIST"))
{
system("ls >tmp.txt");
FILE *fin=fopen("tmp.txt","r");
sprintf(buf, "125\r\n");
send(sock2, buf, strlen(buf), 0);
char temp_buf[10];
while (!feof(fin))
{
fgets(temp_buf, 98, fin);
sprintf(buf, "%s", temp_buf);
if (!active)send(sock1, buf, strlen(buf), 0);
else send(s_data_act, buf, strlen(buf), 0);
}
fclose(fin);
sprintf(buf, "250\r\n");
send(sock2, buf, strlen(buf), 0);
if(!active) close(sock1);
else close(s_data_act);
sprintf(buf, "226\r\n");
send(sock2, buf, strlen(buf), 0);
}
else if(!strcmp(command,"USER"))
{
sprintf(buf, "230\r\n");
send(sock2, buf, strlen(buf), 0);
}
else if(!strcmp(command,"SYST"))
{
write(sock2, "502\r\n", 6);
}
else if(!strcmp(command,"PORT"))
{
unsigned char act_port[2];
int act_ip[4], port_dec;
char ip_decimal[40];
active=1;
sscanf(command, "PORT %d,%d,%d,%d,%d,%d",&act_ip[0],&act_ip[1],&act_ip[2],&act_ip[3], &act_port[0], &act_port[1]);
local_data_addr_act.sin_family=AF_INET;
sprintf(ip_decimal, "%d.%d.%d.%d", act_ip[0], act_ip[1], act_ip[2], act_ip[3]);
local_data_addr_act.sin_addr.s_addr=inet_addr(ip_decimal);
port_dec=act_port[0];
port_dec=port_dec<<8;
port_dec=port_dec+act_port[1];
local_data_addr_act.sin_port=htons(port_dec);
if (connect(s_data_act,(struct sockaddr*)&local_data_addr_act, (int)sizeof(struct sockaddr))!=0)
{
printf("%s%d\n",inet_ntoa(local_data_addr_act.sin_addr),ntohs(local_data_addr_act.sin_port));
sprintf(buf, "425\r\n");
send(sock2, buf, strlen(buf), 0);
close(s_data_act);
}
else
{
sprintf(buf, "200\r\n");
send(sock2, buf, strlen(buf), 0);
}
}
else if(!strcmp(command,"RETR"))
{
sscanf(buf, "%s%s", filename, filename);
stat(filename, &obj);
filehandle = open(filename, O_RDONLY);
size = obj.st_size;
if(filehandle == -1)
size = 0;
send(sock2, &size, sizeof(int), 0);
if(size)
sendfile(sock2, filehandle, NULL, size);
}
else if(!strcmp(command, "STOR"))
{
int c = 0, len;
char *f;
sscanf(buf+strlen(command), "%s", filename);
recv(sock2, &size, sizeof(int), 0);
i = 1;
while(1)
{
filehandle = open(filename, O_CREAT | O_EXCL | O_WRONLY, 0666);
if(filehandle == -1)
{
sprintf(filename + strlen(filename), "%d", i);
}
else
break;
}
f = malloc(size);
recv(sock2, f, size, 0);
c = write(filehandle, f, size);
close(filehandle);
send(sock2, &c, sizeof(int), 0);
}
else if(!strcmp(command, "pwd"))
{
system("pwd>temp.txt");
i = 0;
FILE*f = fopen("temp.txt","r");
while(!feof(f))
buf[i++] = fgetc(f);
buf[i-1] = '\0';
fclose(f);
send(sock2, buf, 100, 0);
}
else if(!strcmp(command, "cd"))
{
if(chdir(buf+3) == 0)
c = 1;
else
c = 0;
send(sock2, &c, sizeof(int), 0);
}
else if(!strcmp(command, "bye") || !strcmp(command, "QUIT"))
{
printf("FTP server quitting..\n");
i = 1;
send(sock2, &i, sizeof(int), 0);
exit(0);
}
}
return 0;
}
答案 0 :(得分:4)
这段代码充满了错误和错误。无论您尝试使用此代码实现什么,它甚至都不能远离符合要求的FTP服务器实现。
您创建了太多套接字,甚至没有使用所有套接字。你在错误的时间在错误的时间创造了一些它们。
大多数套接字/文件函数调用完全没有错误处理。
没有正确处理套接字读/写,特别是没有考虑TCP是一种流传输的事实,它不能保证写和读之间的1对1关系。你必须要考虑到这一点!
有时将INCORRECT数据写入客户端 - 发送不期望的空终止符,发送数据缓冲区,就好像它们实际上是空终止一样,在不期望的情况下将文件大小发送为二进制整数等等。 / p>
假设接收到的数据在实际上没有终止时为空。
将被动模式数据发送到错误的套接字(甚至没有实现PASV
命令开始)。
未正确实施PORT
,STOR
和RETR
命令(对套接字管理不当)。
未正确实施PWD
,CD
和BYE
/ QUIT
命令(发送完全无效的回复)。
而且,虽然技术上不是错误,但你真的不应该使用system()
。有更好的本地方式来获取所需的数据。对于LIST
,您可以使用opendir()
代替,然后根据需要编写目录的条目。对于PWD
,您可以使用getcwd()
。
您需要废弃此代码并重新开始。尝试修复它有太多不妥之处。有关如何正确实现套接字I / O的在线可用的大量示例,尤其是如何使用套接字执行基于行的I / O(因为FTP是基于行的协议)。请阅读RFC 959以了解处理FTP命令/响应和数据传输管理的正确规则。