Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.09.26;
Скачать: CL | DM;

Вниз

WinSock   Найти похожие ветки 

 
Artix   (2004-07-14 10:25) [0]

Нужены исходники простого сканера портов(мультипоточного) или чего нибудть типа этого.
Разобраться с winsock


 
Digitman ©   (2004-07-14 11:09) [1]


> Разобраться с winsock


"разборки" начни с теории

http://book.itep.ru


 
Artix   (2004-07-14 14:59) [2]

С теорией я более менее знаком
Я использовал TclientSocket, ну мне нужну мультипоточную прогу, а на этом компонете такое не сделаешь.
Мне интересует пример на апишках winsock


 
Digitman ©   (2004-07-14 15:29) [3]


> на этом компонете такое не сделаешь


глупости

TclientSocket - всего лишь оболочка того же самого WinsockAPI


 
SergP ©   (2004-07-16 11:14) [4]


> Я использовал TclientSocket, ну мне нужну мультипоточную
> прогу, а на этом компонете такое не сделаешь.


Кто тебе мешает использовать несколько TClientSocket"ов одновременно?


 
Verg ©   (2004-07-17 10:16) [5]

К примеру, вот такую ф-цию можно использовать для сканирования портов.

function PortScanner( const Address : string;
                     StartPort,
                     EndPort : word;
                     TimeOut : integer // В секундах
) : string;
var
Addr:TSockAddr;
Fd, Fds, Fde : PFdSet;
I, K, sRet   : integer;
uK           : u_long;
TmVal        : TTimeVal;
SetSize      : integer;
S            : TSocket;
FStartPort   : word;

begin
Result := "";
if StartPort = 0 then
  StartPort := 1;
SetSize := (EndPort - StartPort) + 1;
if SetSize <= 0 then
  exit;
SetSize := SetSize*sizeof(Fd^.fd_array[0])+sizeof(Fd^.fd_count);
ZeroMemory(@Addr, sizeof(Addr));
Addr.sin_family:=AF_INET;
Addr.sin_addr.S_addr:= inet_addr(pchar(Address));
uK:=1;
TmVal.tv_sec:=TimeOut;
TmVal.tv_usec:=0;

GetMem(Fd,  SetSize);
GetMem(Fds, SetSize);
GetMem(Fde, SetSize);

try
repeat
  FD_ZERO(Fds^);
  FStartPort := 0;
  S := INVALID_SOCKET;
  For i:=StartPort to EndPort do
  begin
    if S<>INVALID_SOCKET then
      closesocket(S);
    S := socket(AF_INET, SOCK_STREAM, 0);
    Addr.sin_port:=htons(word(i));
    if (S <> INVALID_SOCKET) then
    begin
      if  ioctlsocket(S, FIONBIO, uK) <> SOCKET_ERROR then
      begin
        if connect(S, Addr, SizeOf(Addr)) = SOCKET_ERROR then
        begin
          if WSAGetLastError = WSAENOBUFS then
          begin
            closeSocket(S);
            FStartPort := i;
            break
          end;
          if WSAGetLastError <> WSAEWOULDBLOCK then
            continue;
        end;
        FDs^.fd_array[FDs^.fd_count] := S;
        Inc(FDs^.fd_count);
        S:=INVALID_SOCKET;
      end;
    end;
  end;
  while Fds^.fd_count <> 0 do
  begin
    SetSize := Fds^.fd_count*sizeof(Fd^.fd_array[0])+sizeof(Fd^.fd_count);
    move(Fds^, Fd^, SetSize);
    move(Fds^, Fde^, SetSize);
    sRet := select(FD^.fd_count, nil, Fd, Fde, @TmVal);
    if (sRet <= 0)  then
      break;
    for K := 0 to Fd^.fd_count-1  do
    begin
      I := sizeof(Addr);
      if getpeername( FD^.fd_array[K], Addr, I ) <> SOCKET_ERROR then
        Result := Result + IntToStr(ntohs(Addr.sin_port)) + " ";
      FD_CLR(FD^.fd_array[K], Fds^);
      closesocket(FD^.fd_array[K]);
    end;
    for K := 0 to Fde^.fd_count-1  do
    begin
      FD_CLR(FDe^.fd_array[K], Fds^);
      closesocket(FDe^.fd_array[K]);
    end;
  end;
  For K := 0 to Fds^.fd_count-1  do
    closesocket(FDs^.fd_array[K]);
  if FStartPort = 0 then Break;
  StartPort := FStartPort;
until False;
finally
   FreeMem(Fd);
   FreeMem(Fds);
   FreeMem(Fde);
end;
end;


 
Artix   (2004-07-20 09:55) [6]

спасибо.
Еще один вопрос.
Вот я делаю на функция winsock запрос к http серверу.
Отправляю запрос send(), все нормально доходит, а вот ответ сервера то как получить ?


 
Digitman ©   (2004-07-20 09:59) [7]


>  а вот ответ сервера то как получить ?


ну если ты нашел ф-цию send(), то странно что тебе не попалась на глаза ф-ция recv()


 
Artix   (2004-07-20 10:02) [8]

я пробовал ставить после сенда recv но прога просто зависал, и переходила в нечто, названное оутпостом loopback


 
Artix   (2004-07-20 10:02) [9]

Удалено модератором


 
Digitman ©   (2004-07-20 10:18) [10]


> пробовал ставить после сенда recv но прога просто зависал


значит, формат отправленных вызовом send() данных не соответствует протоколу http


 
Artix   (2004-07-20 10:34) [11]

ну тогда бы сервер возвратил bad request

вот код

WSAStartup(makeword(2,0),socks);
sock:=Socket(AF_INET,SOCK_STREAM,0);

addr.sin_family:=AF_INET;

addr2.sin_port:=htons(80);
addr2.sin_addr.S_addr:=inet_addr("127.0.0.1");
addr2.sin_family:=AF_INET;

bind(sock,addr,sizeof(addr));

showmessage(inttostr(connect(sock,addr2,sizeof(addr2))));
buffer:="GET / HTTP/1.0";
send(sock,buffer,sizeof(buffer),0);
recv(sock,buff2,255,0);
Чего надо писать в третьем папрметре recv


 
Digitman ©   (2004-07-20 11:16) [12]

чтот такое buffer, как объявлена эта переменная ?

почему GET-строка не содержит в конце символов перевода строки и возврата каретки ?


 
Artix   (2004-07-20 11:31) [13]

блин, я забыл про #10#10 в конце, все спасибо.буффер - pchar


 
Digitman ©   (2004-07-20 11:38) [14]


> буффер - pchar


как ты думаешь, адрес чего передан тобой 2-м параметром в ф-цию send() ?

как ты думаешь, чему будет равно значение sizeof(buffer) ?


 
Artix   (2004-07-20 11:50) [15]

Понял насчет sizeof но не понял насчет второго параметра, скажи как надо сделать плиз


 
Artix   (2004-07-20 11:55) [16]

все, у меня все заработало !
Подскажи как правильно организовать третий параметр recv (длину данных). Я ведь точно незнаю что серевр передаст


 
Digitman ©   (2004-07-20 11:58) [17]

если 2-й параметр имеет указательный тип (в твоем случае - PChar), то к нему нужно применить оператор разыменования, вот так :

send(..,buffer^,...,...);

тем самым ты указываешь компилятору, что адресом буфера является не компайл-тайм-адрес переменной указ.типа, а фактический ран-тайм-адрес, хранимый в качестве факт.значения этой переменной ... операция эта называется "разыменование переменной" ... запомни !.. это крайне важно !


 
Artix   (2004-07-20 12:02) [18]

я до этого догадался, но длину данных какую ставить в recv.


 
Digitman ©   (2004-07-20 12:06) [19]


> Artix   (20.07.04 11:55) [16]



> Я ведь точно незнаю что серевр передаст


буферизуй принимаемые данные ... при каждом вызове recv() желателен прием данных в размере кратном странице вирт.памяти (4к) ... аккумулируй принимаемые данные ..

после каждого recv() и последующей аккумуляции анализируй (в соответствии с http-протоколом), не принята уже (на сей момент !) в аккумуляторе ЦЕЛОСТНАЯ структура, заканчивающаяся ограничителем  в соответствии с http-протоколом


 
Artix   (2004-07-20 12:13) [20]

while recv(sock,buff2^,10,0)<>0 do
begin
 str1:=str1+string(buff2);
end;
Вот как сделал


 
Digitman ©   (2004-07-20 12:42) [21]

var Bytesreceived: Integer; buff2: PChar;
..
while True  do
begin
GetMem(buff2, 4096);
try
 Bytesreceived := recv(sock,buff2^,4096,0);
 if Bytesreceived > 0 then
   begin
    buff2[Bytesreceived] := #0;
    str1:=str1+string(buff2);
... здесь должен следовать анализ, не содержит на сей момент строка str1 данные в формате ответа на запрос в соответствии с http
   end;
finally
 Freemem(buff2);
end;
end;



Страницы: 1 вся ветка

Текущий архив: 2004.09.26;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.023 c
6-1090150783
banderas
2004-07-18 15:39
2004.09.26
Список всех подключившихся к серваку idTCPServer


1-1094797100
DesWind
2004-09-10 10:18
2004.09.26
Изменение имен компонентов


1-1094663936
Antonmm
2004-09-08 21:18
2004.09.26
Рисование на экране


4-1092944248
surkis
2004-08-19 23:37
2004.09.26
ServiceApplication


4-1092198053
DelphiN!
2004-08-11 08:20
2004.09.26
Как проверить зарегестрирован ли сервис в системе?