Показать сообщение отдельно

  #5  
Старый 13.02.2010, 21:22
rikko
Новичок
Регистрация: 23.11.2009
Сообщений: 14
С нами: 8666774

Репутация: 10
По умолчанию

Код:
procedure TProxyCheckThread.Execute;
var
 sock:LongWord;
 block:u_long;
 SockAddrIn:TSockAddrIn;
 timeout:ttimeval;
 fds:TFDSet;
 rc,curr,len:integer;
 ws:TWSAData;
 send_buf, result:string;
 buf:array[0..4095] of char;

 socks5_req:record // привет
   ver:byte;
   nmet:byte;
   met:byte;
   end;
 socks5_resp:record //ответ на привет
   ver:byte;
   met:byte;
   end;
  socks5_req_TPC:record // куда подключаться
    ver:byte;
    cmd:byte;
    rsv:byte;
    atyp:byte;
    ip:u_long;
    port:u_short;
  end;
  socks5_resp_TPC:record // подключились
    ver:byte;
    cmd:byte;
    rsv:byte;
    atyp:byte;
    ip:u_long;
    port:u_short;
  end;
   

begin
 //приветствие
 socks5_req.ver:=5;
 socks5_req.nmet:=1;
 socks5_req.met:=0;
 WsaStartup($202,ws);
 //запрос соединения
 socks5_req_TPC.ver:=5;
 socks5_req_TPC.cmd:=1;
 socks5_req_TPC.rsv:=0;
 socks5_req_TPC.atyp:=1;
 socks5_req_TPC.ip:=inet_addr(Pansichar(GetipAddress(form1.edit2.Text)));
 socks5_req_TPC.port:=htons(strtoint('80'));


 block:=1;
 sock:=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 if sock=LongWord(-1) then exit;
 SockAddrIn.sin_family := AF_INET;
 SockAddrIn.sin_port := htons(strtoint(PROXY_PORT));
 SockAddrIn.sin_addr.s_addr := inet_addr(Pansichar(PROXY_IP));

 ioctlsocket(sock, FIONBIO, block); // переводим сокет в неблокируемый режим
 if connect(sock, SockAddrIn, SizeOf(SockAddrIn))=SOCKET_ERROR then // пытаемся подключиться
  begin
   if WSAGetLastError=WSAEWOULDBLOCK then // проверяем что сокет перешел в неблокируемый режим
     begin
      FD_ZERO(fds);
      FD_SET(sock,fds);
      timeout.tv_sec:=strtoint(form1.Edit1.Text); // наш таймаут
      timeout.tv_usec:=0;
      rc:=select(0, nil, @fds, nil, @timeout); // ожидаем
     end;
   end;
 block:=0;
 ioctlsocket(sock, FIONBIO, block); // переводим сокет обратно в блокируемый режим
if rc=0 then
 begin
   // сработал таймаут

   synchronize(showresultbad);
 end
else
 begin
   // удачно соединились
  // запрос для http 
   send_buf:='GET http://'+form1.edit2.Text+'/ HTTP/1.1'#13#10+
              'Host: '+form1.edit2.Text+#13#10+
              'Accept: */*'+#13#10+
              'Proxy-Connection: Keep-Alive'+#13#10+
              'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; MRA 4.7 (build 01670); Crazy Browser 1.0.5; .NET CLR 1.1.4322; .NET CLR 2.0.50727)'#13#10#13#10; 


    send(sock,socks5_req, 3,0); // шлем привет
          len := recv(sock, socks5_resp, 2, 0); // считали данные

          if len > 0 then // если есть чтото
          begin
            //смотрим результат
            if (socks5_resp.ver=5) and(socks5_resp.met=0) then //успех
              begin

                send(sock, socks5_req_TPC, 14,0); // запрос на соединение с http сервом
                len := recv(sock,  socks5_resp_TPC, 14, 0); // считали данные
                if len > 0 then
                  if socks5_resp_TPC.cmd=0 then //успех
                    begin

                         send(sock, send_buf[1], length(send_buf),0); // шлем наднные http серву через прокси
                             len := recv(sock,  buf, 4096, 0); // читаем ответ
                             if len > 0 then
                              begin
                                result := copy(buf, 0, len);
                                if pos('200 OK', result)<>0 then result:='GOOD';
                              end;
                    end;

              end;

          end;
     if result='GOOD' then synchronize(showresultgood);

 end;
  closesocket(sock);
  synchronize(dec_count);
end;
реализация для потоков.
реализация таймаута для прокси - взял у Слэша.
прокомментил отстальное.
повторюсь - иногда работает. 200 ok получаю. Очень часто - ошибка 400
 
Ответить с цитированием