I am writing a client-side FTP program, and so far, after a successful connection the server will run in extended passive mode. Using the port number returned from the EPSV
command, I can create client-side sockets like this:
void create_data_channel() {
if ((data_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Cannot create client socket for data connection :(");
exit(1);
}
data_server_addr.sin_family = AF_INET;
data_server_addr.sin_port = htons(port);
data_server_addr.sin_addr = *((struct in_addr *)ftp_server->h_addr);
bzero(&(data_server_addr.sin_zero),8);
// Connect to the ftp server at given port for data connection
if (connect(data_sock, (struct sockaddr *)&data_server_addr,
sizeof(struct sockaddr)) == -1) {
perror("Cannot connect to the ftp server for data connection :(");
exit(1);
}
}
Now, whenever I want to send a command involving the data channel (e.g. LIST
), I can first open a new socket using the method above, and get/send whatever data I need from/to the ftp server. Then, I close the data connection using close(data_sock)
.
This works well for the first LIST
command. However, if I were to try to run two or more LIST
command, the program fails with my error message "Cannot connect to the ftp server for data connection :(". Why is this so? What am I missing here?
答案 0 :(得分:1)
通常,FTP服务器不接受到同一动态端口的多个连接。因此,需要在每次数据传输之前完成PASV
或EPSV
命令,以便服务器创建一个新的侦听套接字并将其端口号返回给客户端。