Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Интернет и сети
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 27.05.2010, 13:50
Аватар для NekitoSSSS
NekitoSSSS NekitoSSSS вне форума
Начинающий
 
Регистрация: 02.05.2009
Адрес: Башкортостан, г.Благовещенск
Сообщения: 142
Версия Delphi: XE
Репутация: 13
Смущение Delphi & WinSock

начал углубляться в сетевое программирование, и спуститься с Indy до WinSock
как пример для изучения хочу сделать софтину, которая будет авторизовываться на сайте (методом post. куки приходят, так что их тоже надо сохранять, и отправлять при последующих запросах... )
и брать кое какие данные... (парсить страницу это не проблема )
с GET знаком, с POST - не очень, т.к. пока что не получается правильно сформировывать данные для отправки и распарсивать принятые данные...

кто чем может помочь в изучении??!!
к поисковикам не посылать, слишком уж это для вас обыденно просто...
Ответить с цитированием
  #2  
Старый 27.05.2010, 19:10
Аватар для NekitoSSSS
NekitoSSSS NekitoSSSS вне форума
Начинающий
 
Регистрация: 02.05.2009
Адрес: Башкортостан, г.Благовещенск
Сообщения: 142
Версия Delphi: XE
Репутация: 13
По умолчанию

особенно интересуют неблокирующие сокеты, а так же информация о том как отправлять, принимать и в цикле ожидать данные с сервера.
подскажите пожалуйста кто что знает((

p.s. все мы когда-то были нубами((
Ответить с цитированием
  #3  
Старый 27.05.2010, 20:15
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

ну если в цикле ожидать ответ сервера, то сокет должен быть блокируемым, имхо
пример автризации на одном форуме :
PHP код:
unit Unit1;

interface

uses
  ScktComp
,
  
WindowsMessagesSysUtilsVariantsClassesGraphicsControlsForms,
  
DialogsStdCtrls;

type
  TForm1 
= class(TForm)
    
Button1TButton;
    
Memo1TMemo;
    
procedure Button1Click(SenderTObject);
  private
    { Private 
declarations }
  public
    { Public 
declarations }
  
end;

var
  
Form1TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(SenderTObject);
var
  
clientsocketTClientSocket;
  
requestString;
  
request_dataString;
  
savetickcountCardinal;
  
cChar;
  
responseString;

  
usernameString;
  
passwordString;

begin

  username
:='**********';
  
password:='**********';

  
clientsocket:=TClientSocket.Create(Self);
  try
    
clientsocket.ClientType:=ctBlocking;
    
clientsocket.Port:=80;
    
clientsocket.Host:='forum29.ru';
    
clientsocket.Open;
    try
      
//  post данные
      
request_data:='vb_login_username='+username+'&vb_login_password='+password+'&cookieuser=1&s=&securitytoken=guest&do=login&vb_login_md5password=&vb_login_md5password_utf=';
      
//  готовим post запрос
      
request:='';
      
request:=request+'POST /login.php?do=login HTTP/1.1'+#13#10;
      
request:=request+'Host: forum29.ru'+#13#10;
      
request:=request+'Connection: close'+#13#10;
      
request:=request+'Proxy-Connection: close'+#13#10;
      
request:=request+'User-Agent: Mozilla/4.0'+#13#10;
      
request:=request+'Content-Type: application/x-www-form-urlencoded'+#13#10;
      
request:=request+'Content-Length: '+IntToStr(Length(request_data))+#13#10;
      
request:=request+#13#10;
      //  отсылаем серверу
      
clientsocket.Socket.SendText(request);
      
clientsocket.Socket.SendText(request_data);
      
//  то что послали серверу
      
Memo1.Lines.Add(request);
      
Memo1.Lines.Add(request_data);
      
Memo1.Lines.Add('--');
      
//  теперь читаем его ответ
      //  читаем заголовок ответа
      //  1 мин таймаут
      
savetickcount:=GetTickCount;
      
response:='';
      while 
clientsocket.Socket.Connected and (GetTickCount-savetickcount<60000) do
      
begin
        
if clientsocket.Socket.ReceiveLength>0 then
        begin
          clientsocket
.Socket.ReceiveBuf(c1);
          
response:=response+c;
          if (
Length(response)>=4) and (Copy(responseLength(response)-34)=#13#10#13#10) then Break;
        
end else Sleep(10);
      
end;
      
//  вот заголовок
      //  чтобы собрать куки обрабатываем строки с Set-Cookie
      //  response можно засунуть в отдельный TStrings, чтобы удобней было его парсить
      
Memo1.Lines.Add(response);
      
Memo1.Lines.Add('--');
      
//  читаем страницу
      //  т.к. этот сервер передает чанками
      //  Transfer-Encoding: chunked
      //  ждем ответа макс 10 сек
      //  либо "руками" обрабатываем чанки и выходим когда все принято
      //  но это уже совсем другая история
      //  конечно проще когда есть Content-Length в заголовке, имхо
      
savetickcount:=GetTickCount;
      
response:='';
      while 
clientsocket.Socket.Connected and (GetTickCount-savetickcount<10000) do
      
begin
        
if clientsocket.Socket.ReceiveLength>0 then
        begin
          clientsocket
.Socket.ReceiveBuf(c1);
          
response:=response+c;
        
end;
      
end;
      
//  вот страница
      
Memo1.Lines.Add(response);
      
Memo1.Lines.Add('--');
    
finally
      clientsocket
.Close;
    
end;
  
finally
    clientsocket
.Free;
  
end;
end;

end
Ответить с цитированием
  #4  
Старый 27.05.2010, 20:17
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

PHP код:
request_data:='vb_login_username='+username+'&vb_login_password='+password+'&cookieuser=1&s=&securitytoken=guest&do=login&vb_login_md5password=&vb_login_md5password_utf='
взято с формы авторизации на форуме
Ответить с цитированием
  #5  
Старый 28.05.2010, 11:56
Аватар для NekitoSSSS
NekitoSSSS NekitoSSSS вне форума
Начинающий
 
Регистрация: 02.05.2009
Адрес: Башкортостан, г.Благовещенск
Сообщения: 142
Версия Delphi: XE
Репутация: 13
По умолчанию

эЭЭ чувак, ты похоже немного перепутал! мне нужна инфа про WinSock а не про TClientSocket (TClientSocket`Ы увеличивают размер проги на десятки килобайт, а мне нужно чисто на апи, чтоб прога весила не больше 60кб ... )
ну впринципе и за это спс)))

Последний раз редактировалось NekitoSSSS, 28.05.2010 в 11:59.
Ответить с цитированием
  #6  
Старый 28.05.2010, 21:23
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

упс. подумал, что основной вопрос все-таки про POST, поэтому и выдал как проще. если никто не ответит выдам на выходных на голом Windows Sockets 2 (постараюсь) сейчас лень
Ответить с цитированием
  #7  
Старый 28.05.2010, 23:18
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,906
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

Вообще-то разницы нет, подход-то правильный. А как там сокет создается - дело десятое.
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
  #8  
Старый 29.05.2010, 11:36
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

переделал предыдущий пример (только до чтения заголовка, остальное по аналогии):
PHP код:
unit Unit1;

interface

uses
  WinSock
,
  
WindowsMessagesSysUtilsVariantsClassesGraphicsControlsForms,
  
StdCtrls;

type
  TForm1 
= class(TForm)
    
Button1TButton;
    
Memo1TMemo;
    
procedure Button1Click(SenderTObject);
  private
    { Private 
declarations }
  public
    { Public 
declarations }
  
end;

var
  
Form1TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(SenderTObject);
var
  
WSADataTWSAData;
  
ErrorCodeInteger;
  
FSocketTSocket;
  
HostEntPHostEnt;
  
InAddrTInAddr;
  
FAddrTSockAddrIn;
  
BlockingLongint;
  
argInteger;

  
requestString;
  
request_dataString;
  
savetickcountCardinal;
  
cChar;
  
responseString;

  
usernameString;
  
passwordString;
begin
  username
:='**********';
  
password:='**********';

  
ErrorCode:=WSAStartup($0101WSAData);
  if 
ErrorCode<>0 then raise Exception.Create('WSAStartup');
  try
    
FSocket:=socket(PF_INETSOCK_STREAM0);
    if 
FSocket=INVALID_SOCKET then raise Exception.Create('socket');

    
HostEnt:=gethostbyname('forum29.ru');
    
FillChar(InAddrSizeOf(InAddr), 0);
    if 
HostEnt<>nil then
    begin
      InAddr
.S_un_b.s_b1:=HostEnt^.h_addr^[0];
      
InAddr.S_un_b.s_b2:=HostEnt^.h_addr^[1];
      
InAddr.S_un_b.s_b3:=HostEnt^.h_addr^[2];
      
InAddr.S_un_b.s_b4:=HostEnt^.h_addr^[3];
    
end else raise Exception.Create('gethostbyname');
    
FAddr.sin_family:=PF_INET;
    
FAddr.sin_addr:=InAddr;
    
FAddr.sin_port:=htons(80);

    
Blocking:=0;
    
ioctlsocket(FSocketFIONBIOBlocking);

    
ErrorCode:=connect(FSocketFAddrSizeOf(FAddr));
    if 
ErrorCode<>0 then raise Exception.Create('connect');

    try
      
//  post данные
      
request_data:='vb_login_username='+username+'&vb_login_password='+password+'&cookieuser=1&s=&securitytoken=guest&do=login&vb_login_md5password=&vb_login_md5password_utf=';
      
//  готовим post запрос
      
request:='';
      
request:=request+'POST /login.php?do=login HTTP/1.1'+#13#10; 
      
request:=request+'Host: forum29.ru'+#13#10; 
      
request:=request+'Connection: close'+#13#10; 
      
request:=request+'Proxy-Connection: close'+#13#10; 
      
request:=request+'User-Agent: Mozilla/4.0'+#13#10;
      
request:=request+'Content-Type: application/x-www-form-urlencoded'+#13#10; 
      
request:=request+'Content-Length: '+IntToStr(Length(request_data))+#13#10; 
      
request:=request+#13#10; 
      //  отсылаем серверу 

      
send(FSocketPointer(request)^, Length(request), 0);
      
send(FSocketPointer(request_data)^, Length(request_data), 0);

      
//  то что послали серверу
      
Memo1.Lines.Add(request);
      
Memo1.Lines.Add(request_data);
      
Memo1.Lines.Add('--');
      
//  теперь читаем его ответ
      //  читаем заголовок ответа
      //  1 мин таймаут
      
savetickcount:=GetTickCount;
      
response:='';

      while 
GetTickCount-savetickcount<60000 do
      
begin
        ioctlsocket
(FSocketFIONREADarg);
        if 
arg>0 then
        begin
          recv
(FSocketc10);
          
response:=response+c;
          if (
Length(response)>=4) and (Copy(responseLength(response)-34)=#13#10#13#10) then Break;
        
end else Sleep(10);
      
end;
      
//  вот заголовок 
      //  чтобы собрать куки обрабатываем строки с Set-Cookie 
      //  response можно засунуть в отдельный TStrings, чтобы удобней было его парсить 
      
Memo1.Lines.Add(response); 
      
Memo1.Lines.Add('--');
    
finally
      ErrorCode
:=closesocket(FSocket);
      if 
ErrorCode<>0 then raise Exception.Create('closesocket');
    
end;
  
finally
    ErrorCode 
:= WSACleanup;
    if 
ErrorCode<>0 then raise Exception.Create('WSACleanup');
  
end;
end;

end
Ответить с цитированием
  #9  
Старый 29.05.2010, 14:12
Аватар для NekitoSSSS
NekitoSSSS NekitoSSSS вне форума
Начинающий
 
Регистрация: 02.05.2009
Адрес: Башкортостан, г.Благовещенск
Сообщения: 142
Версия Delphi: XE
Репутация: 13
По умолчанию

результат работы твоего кода.. это нормально?!
Изображения
Тип файла: jpg winsock.JPG (35.8 Кбайт, 50 просмотров)
Ответить с цитированием
  #10  
Старый 29.05.2010, 14:43
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

ну уж с кодировкой то сам. основную цель код выполняет.
Ответить с цитированием
  #11  
Старый 29.05.2010, 14:47
Аватар для NekitoSSSS
NekitoSSSS NekitoSSSS вне форума
Начинающий
 
Регистрация: 02.05.2009
Адрес: Башкортостан, г.Благовещенск
Сообщения: 142
Версия Delphi: XE
Репутация: 13
По умолчанию

виновата кодировка о_О ? а почему тогда HTTP Analyzer не показывает что что-то вообще отправилось и принялось? или что-то другое посоветуешь для мониторинга траффика?
Ответить с цитированием
  #12  
Старый 29.05.2010, 14:49
Аватар для NekitoSSSS
NekitoSSSS NekitoSSSS вне форума
Начинающий
 
Регистрация: 02.05.2009
Адрес: Башкортостан, г.Благовещенск
Сообщения: 142
Версия Delphi: XE
Репутация: 13
По умолчанию

да, кстати если закоментировать строку
Код:
if (Length(response)>=4) and (Copy(response, Length(response)-3, 4)=#13#10#13#10) then Break;
то данные приходят... правда не те конечно которые хотелось бы видеть, то есть виден только ответ... без заголовков...
Ответить с цитированием
  #13  
Старый 29.05.2010, 14:57
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

поставь точку останова на
PHP код:
response:=response+c
и см. что в "с" прихотит. правильней еще recv() сделать как if recv()>0
Цитата:
if recv(FSocket, c, 1, 0)>0 then response:=response+c;

Последний раз редактировалось NumLock, 29.05.2010 в 14:59.
Ответить с цитированием
  #14  
Старый 29.05.2010, 15:15
Аватар для NekitoSSSS
NekitoSSSS NekitoSSSS вне форума
Начинающий
 
Регистрация: 02.05.2009
Адрес: Башкортостан, г.Благовещенск
Сообщения: 142
Версия Delphi: XE
Репутация: 13
По умолчанию

сори конечно, но после того как перенес данный код в D7 то все стало работать как часы, в т.ч. сниффер заметил активность проги ))) все, возвращаюсь обратно на D7 с этого тупого embarcadero RadStudio 2010
Ответить с цитированием
  #15  
Старый 29.05.2010, 16:18
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

а разобраться с RadStudio 2010 нет желания?
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 23:13.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter