Ubuntu中的FTP活动模式客户端错误:我不会打开到127.0.1.1的连接

时间:2014-12-16 07:15:54

标签: c ubuntu ftp localhost host

我创建了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

1 个答案:

答案 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)作为数据连接的本地地址。