Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Сети > FTP client & proxy проблема


Автор: AHTOXA 4.1.2006, 17:35
Привет всем. В proxy и ftp я не специалист. Написал ftp клиента. Необходимо:
1) заставить работать его через proxy
2) заставить работать его через proxy, если proxy прозрачен для данного порта.

Как это сделать?

Автор: Aleksandor 4.1.2006, 19:37
Мне кажется если прокси прозрачный то ничего делать не надо, на то он и прозрачный smile
Кстати а какого типа прокси? Через HTTP он все равно работать вряд ли будет, если SOCKS тогда другое дело.

Автор: DeadSoul 4.1.2006, 22:38
AHTOXA, код публикуй. Если твой код использует MFC, то прижется забить на MFC. MFC через проксю с паролем непробъетсся

Автор: Aleksandor 5.1.2006, 11:50
Попробуй юзать функции WinInet

Автор: AHTOXA 5.1.2006, 12:40
MFC не использую. Только родные WINDOWS библиотеки + свои надстройки над этими библиотеками, для коннекта использую сокеты.
Для прозрачного proxy такая проблема:

например есть прокси сервер 0.0.0.1, ftp сервер - 0.0.0.2 и адрес моей машины 0.0.0.0
Control connection на 0.0.0.2 проходит без проблем. Теперь разберемся с Data connection:
я делаю bind(0.0.0.0), затем отсылаю команду "PORT 0,0,0,0,p1,p2" - но это адрес внутри сети, и 0.0.0.2 не сможет законектиться по этому адресу. Для встроенного в far FTP клиента проходит команда - PORT 0,0,0,1,p1,p2 при создании Data connection. Я пробовал сделать bind для 0.0.0.1 - но не проходит.

Автор: AHTOXA 5.1.2006, 12:47
Код

int SLAPI FTP::Connect(FTPAccount * pAccount)
{
    int ok = 1;
    char buf[256];
    SString reply;
    InetAddr addr;

    THROW_PP(pAccount, PPERR_INVPARAM);
    Account = *pAccount;
    addr.Set(Account.Host, Account.Port);
    THROW_MEM(P_ControlConn = new TcpSocket(Account.Timeout, 1));
    THROW_PP(P_ControlConn->Connect(addr), PPERR_SLIB);
    THROW(GetReply(reply));
    THROW(CheckReply(reply));
    THROW(SendCmd(FTPCMD_USER, (long)Account.User));
    THROW(SendCmd(FTPCMD_PASS, (long)Account.Password));
    CATCH
        ok = (Disconnect(), 0);
    ENDCATCH
    return ok;
}

int SLAPI FTP::FileTransfer(const char * pLocalPath, const char * pServerPath, int send)
{
    int ok = 1;
    const char * p_type = "I";
    char name[256];
    char drv[MAXDRIVE], dir[MAXDIR], fname[MAXFILE + MAXEXT], ext[MAXEXT];
    DWORD namelen = sizeof(name);
    FILE * p_file = 0;
    SString str_addr;
    InetAddr addr;
    TcpSocket ftp_conn(Account.Timeout, 1);
    
    fnsplit(pServerPath, drv, dir, fname, ext);
    strcat(strcat(fname, "."), ext);
    if(dir[0] != '\0')
        THROW(CD(dir));

    //addr.Set(ADDR_ANY);
    GetComputerName(name, &namelen);
    addr.Set(name, 0);
    THROW_PP(ftp_conn.Bind(addr), PPERR_SLIB);
    THROW_PP(ftp_conn.GetSockName(&addr), PPERR_SLIB);

    addr.ToStr(InetAddr::fmtAddr, str_addr);
    str_addr.ReplaceChar('.', ',');
    str_addr.Cat(",");
    str_addr.Cat((long)(addr.GetPort() & 0x00ff));
    str_addr.Cat(",");
    str_addr.Cat((long)((addr.GetPort() >> 8) & 0x00ff));

    SendCmd(FTPCMD_TYPE, (long)p_type);
    SendCmd(FTPCMD_PORT, (long)(const char*)str_addr);
    if(send)
        SendCmd(FTPCMD_STOR, (long)fname);
    else
        SendCmd(FTPCMD_RETR, (long)fname);
    THROW_PP(ftp_conn.Listen(), PPERR_SLIB);
    if(ftp_conn.Select(TcpSocket::mRead)) {
        InetAddr cli_addr;
        TcpSocket cli_sock;
        if(ftp_conn.Accept(&cli_sock, &cli_addr)) {
            char buf[512];
            size_t len = 0;
            SLibError = SLERR_OPENFAULT;
            PPSetAddedMsgString(pLocalPath);
            if(send) {
                THROW_PP((p_file = fopen(pLocalPath, "rb")) != NULL, PPERR_SLIB);
                while((len = fread(buf, 1, sizeof(buf), p_file)))
                    THROW(cli_sock.Send(buf, len, 0));
            }
            else {
                THROW_PP((p_file = fopen(pLocalPath, "wb")) != NULL, PPERR_SLIB);
                while(cli_sock.Recv(buf, sizeof(buf), &len) > 0 && len != 0)
                    fwrite(buf, 1, len, p_file);
            }
            cli_sock.Disconnect();
        }
    }
    CATCH
        ok = 0;
    ENDCATCH
    if(p_file)
        fclose(p_file);
    return ok;
}


Автор: Aleksandor 5.1.2006, 13:27
а пробовал bind к INADDR_ANY ??

Автор: AHTOXA 5.1.2006, 15:54
Пробовал ADDR_ANY, судя по #define ADDR_ANY INADDR_ANY (WinSock2.h)
это одно и тоже - та же редиска smile (в данном случае непонятно какой адрес отправлять командой PORT)

Автор: Aleksandor 5.1.2006, 16:10
Короче надо разбираться smile А что адреса такие 0.0.0.0 "this" network? Может другой диапазон попробовать, ну 192.168.1.0 например...
Вот здесь можно скачать исходники FTP клиента и сервера и еще там много чего полезного http://filezilla-project.org/

Автор: AHTOXA 5.1.2006, 16:15
Адреса в сети естественно другие, просто для примера привел с нулями smile

Автор: AHTOXA 8.1.2006, 12:55
Пришлось таки перейти на использование библиотеки WinInet.dll.
В связи с чем вопрос. Функция FtpFindFirstFile, возвращает дату время не всегда корректную. Иногда бывает что год = текущий год - 1, с чем это связано?

Автор: Aleksandor 8.1.2006, 18:18
Попробуй поискать в Google GROUPS по фразе "FtpFindFirstFile"
Там много чего интересного. Даже есть группа новостей по программированию в WinInet
называется microsoft.public.inetsdk.programming.wininet

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)