assmer |
Отправлено: 04.03.2006, 10:59 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 3
|
Если у кого ни будь есть возможность, выложите пожалуйста рабочий код функции которая используя API подключалась бы к какому ни будь сайту и скачивала с него какую ни будь страницу. Заранее благодарен. |
|
AVC |
Отправлено: 06.03.2006, 10:48 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
CODE |
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Загрузка страницы через сокеты
//---------------------------------------------------------------------------
void __fastcall TForm1::Bt_GetSiteClick(TObject *Sender)
{
AxSock_Init();
SOCKET mysocket = INVALID_SOCKET;
AnsiString text = AnsiString("") + "\
GET [URL=http://www.cbuilder.ru/forums/index.php]http://www.cbuilder.ru/forums/index.php[/URL] HTTP/1.0\r\n\
Accept: */*\r\n\
Accept-Language: ru\r\n\
Pragma: no-cache\r\n\
User-Agent: XXX\r\n\
Host: www.cbuilder.ru\r\n\
Proxy-Connection: Keep-Alive\r\n\
\r\n\
\r\n\
";
try { // 240 — мой прокси, ходим черз порт 8080
text = PostExecute(mysocket, "10.111.96.240", 8080, text, 6000);
}
catch (Exception &xcp) { ShowMessage(xcp.Message); }
Memo1->Lines->Text = text;
if (mysocket != INVALID_SOCKET)
{ closesocket(mysocket);
mysocket = INVALID_SOCKET;
}
AxSock_DeInit();
}
//---------------------------------------------------------------------------
// Выполнить отправку и дождаться ответа
//---------------------------------------------------------------------------
AnsiString __fastcall TForm1::PostExecute (SOCKET& pSocket
,const AnsiString& IP
,int Port
,const AnsiString &PostText
,int waitms // ждать овет ms 0-не ждать
)
{
int ret;
if (pSocket != INVALID_SOCKET)
{ closesocket(pSocket);
pSocket = INVALID_SOCKET;
}
// AF_INET SOCK_STREAM/SOCK_DGRAM ... _UDP/_IP/_TCP
pSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (pSocket == INVALID_SOCKET) throw Exception(" socket error " + WSAErrorAsText());
// Устанавливаем предельное время ожидания ответа
int timeout = 3000;
if (waitms > 0) timeout = waitms;
setsockopt(pSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
sockaddr_in sadr_trg;
sadr_trg.sin_family = AF_INET;
sadr_trg.sin_addr.s_addr = inet_addr(IP.c_str());
sadr_trg.sin_port = htons (Port);
ret = connect(pSocket, (sockaddr*)&sadr_trg, sizeof(sadr_trg));
if (ret == SOCKET_ERROR) throw Exception(" connect error " + WSAErrorAsText());
ret = send(pSocket, PostText.c_str(), PostText.Length(), 0);
if (ret == SOCKET_ERROR) throw Exception(" send error " + WSAErrorAsText());
AnsiString answertext = "";
if (waitms > 0)
{ char buf[0xFFF0]; memset(buf, 0x00, sizeof(buf));
int rcou = 0;
int retr = recv(pSocket, buf, sizeof(buf), 0 /*MSG_PEEK*/);
if (retr == SOCKET_ERROR)
{ AnsiString errmsg = " recv error " + WSAErrorAsText();
closesocket(pSocket); pSocket = INVALID_SOCKET;
throw Exception(errmsg);
}
while(retr > 0)
{ rcou += retr;
retr = recv(pSocket, buf+rcou, sizeof(buf) — rcou, 0);
// надо более строгий анализ на версию протокола, но не в этом проекте
// для HTTP/1.1 и chunced в конце текста html стоит 0D0A300D0A0D0A
if ((buf[rcou+retr-7] & 0xFF) == 0x0D &&
(buf[rcou+retr-6] & 0xFF) == 0x0A &&
(buf[rcou+retr-5] & 0xFF) == 0x30 &&
(buf[rcou+retr-4] & 0xFF) == 0x0D &&
(buf[rcou+retr-3] & 0xFF) == 0x0A &&
(buf[rcou+retr-2] & 0xFF) == 0x0D &&
(buf[rcou+retr-1] & 0xFF) == 0x0A )
{
break;
}
}
answertext = AnsiString(buf);
}
ret = closesocket(pSocket);
if (ret == SOCKET_ERROR) throw Exception(" close connect error " + WSAErrorAsText());
pSocket = INVALID_SOCKET;
return answertext;
}
//---------------------------------------------------------------------------
|
Функции AxSock_Init / Deinit — просто инициализация библиотеки сокетов. Естественно у меня это все выделено в отдельный модуль, просто подключаемый к проекту. Так же в тексте используются переменные и функции из этого модуля. Их смысл понятен из названия. Будет что не ясно — спрашивайте.
Для получения ВСЕЙ страницы нужно проанализировать полученный текст и выполнить все необходимые ссылки (типа css, js и прочее).
Отредактировано AVC — 09/03/2006, 08:05 |
|
assmer |
Отправлено: 06.03.2006, 22:36 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 3
|
ret = bind (pSocket, (sockaddr*)&sadr_src, sizeof(sadr_src));
А разве в этой строчке есть необходимость, мне кто то говорил что bind нужна только в случае создания сервера.
|
|
_NIK_ |
Отправлено: 07.03.2006, 01:53 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 55
|
QUOTE (assmer @ 06/03/2006, 22:36) | ret = bind (pSocket, (sockaddr*)&sadr_src, sizeof(sadr_src));
А разве в этой строчке есть необходимость, мне кто то говорил что bind нужна только в случае создания сервера. |
Bind нужна и для сервера и для клиента — основная функция создания сокета — она связывает переменную SOCKET и непосредственно глобальный идентификатор на тачке, после кот. появляется порт!
|
|
Guest |
Отправлено: 07.03.2006, 10:09 |
|
Не зарегистрирован
|
Что то у меня не выходит может из за того что сделал некотороые замены:
- Заменил AxSock_Init() на :
WSADATA WS;
WSAStartup(0x101,&WS);
- Заменил WSAErrorAsText на WSAGetLastError() (у меня ту функцию не понимает и Help её не знает)
- Заменил перед вызовом (bind)
sadr_src.sin_addr.s_addr = inet_addr(AxS_LocalIP.c_str());
на
sadr_src.sin_addr.s_addr = INADDR_ANY;
(Не понимает AxS_LocalIP)
- Если ставить порт 8080 то вообще не конектица если ставить порт 80 то конектица но ни чего на запросы не отвечает.
|
|
AVC |
Отправлено: 07.03.2006, 11:46 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE |
ret = bind (pSocket, (sockaddr*)&sadr_src, sizeof(sadr_src));
А разве в этой строчке есть необходимость
|
Да, спасибо, не нужна. Затесалась от НЕ ориентированного на соединение клиента.
QUOTE |
мне кто то говорил что bind нужна только в случае создания сервера.
|
Это не вся правда о bind. |
|
AVC |
Отправлено: 07.03.2006, 12:02 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE |
Если ставить порт 8080 то вообще не конектица если ставить порт 80 то конектица но ни чего на запросы не отвечает.
|
В примере МОЙ прокси и МОЙ порт на прокси. У вас свои.
QUOTE |
Что то у меня не выходит может из за того что сделал некотороые замены:
|
Прикрепляю библиотечный модуль, если подойти творчески — все должно получиться. Не выйдет — сделаю отдельным проектом.
Подозреваю нет ответа из-за AxS_LocalIP это МОЙ IP адрес, надо было подставить свой.
|
|
assmer |
Отправлено: 07.03.2006, 13:39 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 3
|
Если не нужен bind тогда не нужена и структура sadr_src а значит не пригодится и AxS_LocalIP так что не он причина, причина в чем то еще. |
|
AVC |
Отправлено: 09.03.2006, 09:03 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE (assmer @ 07/03/2006, 12:39) | Если не нужен bind тогда не нужена и структура sadr_src а значит не пригодится и AxS_LocalIP так что не он причина, причина в чем то еще. |
Справедливо. Но этот код (даже в исходном виде, с bind) у меня реально работает как в рамках локальной сети — для опроса некоторых устройств, поддерживающих http; в корпоративной сети — получение информации от сервереров; опробован, но пока не пригодился, в глобальной сети.
Чем еше помочь не знаю. Посмотрите настройки сети. А может не правильно сформулирован запрос? Поставьте снифер, снимите протокол при доступе через web-browser, посмотрите запросы и ответы.
Или давайте ваш запрос — попробую выполнить у себя.
Кстати, посмотрите на содержимое строки запроса — GET. В в оригинале она выглядит несколькр иначе (происки движка форума ) |
|