我创建了FTP Active模式客户端。在OS X操作系统上,它运行良好。但是当我迁移到Ubuntu时,它已经开始失败了。问题是在OS X上,当我启用数据连接时,我的侦听套接字会侦听我的wifi路由器IP。我不知道为什么,但在我的Ubuntu上它会监听127.0.1.1。因此,我得到了对我的PORT的回应:
I won't open a connection to 127.0.1.1
如何像在OS X中那样优先考虑主机?
数据连接:
else if (strcmp(command, "ls") == 0)
{
// Listening data socket initialization
data_socket = listen_to_server(&ip_address);
if (data_socket == SOCKET_ERROR)
{
goto EXIT;
}
// FTP commad PORT request
if(request_port(&command_socket, ip_address) == SOCKET_ERROR)
{
goto EXIT;
}
// Server response receiving
if(receive_packet(&command_socket, packet) == SOCKET_ERROR)
{
goto EXIT;
}
// Server response printing
printf ("%s\n", packet);
// FTP command LIST request
if(request_list(&command_socket) == SOCKET_ERROR)
{
goto EXIT;
}
// Server response receiving
if(receive_packet(&command_socket, packet) == SOCKET_ERROR)
{
goto EXIT;
}
// Server response printing
printf ("%s\n", packet);
// Server connection accepting (Active mode)
int address_size = sizeof(struct sockaddr_in);
struct sockaddr_in remote_address;
data_socket_server = accept(data_socket, (struct sockaddr *)&remote_address, (socklen_t *)&address_size);
// Server response receiving
if(receive_packet(&command_socket, packet) == SOCKET_ERROR)
{
goto EXIT;
}
// Server response printing
printf ("%s\n", packet);
// Server data receiving
if(receive_packet(&data_socket_server, packet) == SOCKET_ERROR)
{
goto EXIT;
}
// Server data printing
printf ("%s\n", packet);
// Sockets closing
closesocket(data_socket_server);
closesocket(data_socket);
}
侦听套接字创建:
// Listening to server function
SOCKET listen_to_server(char **ip)
{
// SOCKET variable
SOCKET data_socket;
// SOCKET address structure
struct sockaddr_in socket_address;
// Listening host name
char host_name [256] = {0};
// Listening host entry
struct hostent *host_entry;
// Host name initialization
if (gethostname(host_name, sizeof(host_name)) == INVALID_SOCKET)
{
printf("Error: failed to get host name\n");
return INVALID_SOCKET;
}
// Host entry structure initialization
if ((host_entry = gethostbyname(host_name)) == NULL)
{
printf("Error: failed to get host by name \'%s\'\n", host_name);
return INVALID_SOCKET;
}
// Socket address structure initialization
socket_address.sin_family = AF_INET;
socket_address.sin_port = htons(DATA_PORT);
socket_address.sin_addr = *(struct in_addr *)host_entry -> h_addr;
memset (&(socket_address.sin_zero), 0, 8);
// Socket initialization
if ((data_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
printf("Error: failed to initialize socket\n");
return INVALID_SOCKET;
}
// Socket and address binding
if (SOCKET_ERROR == bind(data_socket, (struct sockaddr *)&socket_address, sizeof(socket_address)))
{
printf("Error: failed to bind socket\n");
closesocket(data_socket);
return INVALID_SOCKET;
}
// Socket seting as listening
if (SOCKET_ERROR == listen(data_socket, MAX_QUEUE_LENGTH))
{
printf("Error: failed to set socket as listening\n");
closesocket (data_socket);
return INVALID_SOCKET;
}
*ip = inet_ntoa(*(struct in_addr *)host_entry -> h_addr);
return data_socket;
}
此外,netstat不显示监听数据soxket外地地址:
tcp 0 0 127.0.1.1:1024 0.0.0.0:* LISTEN
答案 0 :(得分:0)
if ((host_entry = gethostbyname(host_name)) == NULL)
...
socket_address.sin_addr = *(struct in_addr *)host_entry -> h_addr;
...
if (SOCKET_ERROR == bind(data_socket, (struct sockaddr *)&socket_address, sizeof(socket_address)))
看起来您只是假设系统的本地配置主机名将解析为外部地址。这个假设是错误的。
相反,您应该使用FTP控制连接的本地地址(getsockname
)作为数据连接的本地地址。