Тема: Delphi & WinSock
Показать сообщение отдельно
  #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
Ответить с цитированием