ClientSocket
Слушаю порт с помощью ServerSocket.
Хочу чтоб ClientSocket скнировал локальные адреса 192.168.0.0 - 192.168.0.255 чтоб прога увидела сервер.
Как узнать что нет коннекта?
Наверное в событии OnError ClientSocket'а?
Пихаю в цикл попытки коннекта ClientSocket'а, но событие OnError происходит только при выходе из цикла.
Как мне организовать такую штуку?
Например в StarCraft или дугих играх вижу имя сервера (кто создал сетевую игру), потом просто коннекчусь к нему.
Next:
.
.
.
try
ClientSocket.Open;
except
Error:=true;
finally
goto Next;
Но надо учесть, что ClientSocket довольно долго пытается соедениться, прежде чем выдать ошибку, так что если у тебя десяток возможных адресов... Может быть есть где-нибудь у него свойство типа TimeOut, но на первый взгляд не видно. То есть так и так, по видимому придется лезть через Win API - искать там подходящие функции.
for i := 1 to 255 do begin
ClientSocket1.Host := '192.168.1.' + IntToStr (i);
ClientSocket1.Port := 21;
ClientSocket1.Open;
end;
заставят его просто перебрать все порты, а непосредственно попытка соединения произойдёт только для последнего, что у тебя и твориться. Понимаешь, в момент работы Open ты меняешь адрес и снова вызываешь Open, он, не закончив попытку предыдущего коннекта, лезет на новый, его опять обрывают и т.д. И только самый последний вызов отрабатывает до конца (ошибка - это значит, что коннект невозможен, вот и всё.
Принцп сканирования ClientSocket'ом заключается в том, чтобы, дав команду на соединение, в событиях OnError и OnConnect отреагировать на него (т.е. завершить сканирование, ибо попытаться соединиться со слеующим портом). Выглядит это примерно так (сия прога сканирует локальную сеть с 192.168.1.1 по 192.168.1.255 по 80 порту):
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ScktComp, StdCtrls;
const
First = 1;
Last = 255;
Current: integer = First;
Stopped: boolean = FALSE;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
cs: TClientSocket;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure csConnect(Sender: TObject; Socket: TCustomWinSocket);
procedure csError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure ConnectNext;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
cs.Host := '192.168.1.' + IntToStr (Current);
cs.Port := 80;
Memo1.Lines.Clear;
Stopped := FALSE;
cs.Open;
end;
procedure TForm1.ConnectNext;
begin
if cs.Active then
cs.Close;
if Stopped then
Exit;
Inc (Current);
if Current > Last then
Exit;
cs.Host := '192.168.1.' + IntToStr (Current);
cs.Open;
end;
procedure TForm1.csConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
Memo1.Lines.Add (Socket.RemoteHost + '(' + Socket.RemoteAddress + ') - Ok!');
ConnectNext;
end;
procedure TForm1.csError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
Memo1.Lines.Add (cs.Host + ' - ' + IntToStr (ErrorCode));
ErrorCode := 0;
ConnectNext;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Stopped := TRUE;
end;
end.
Учти, при этом, что Fantasist, сказав, что ClientSocket "довольно долго пытается соединиться", выразился очень мягко. TClientSocket просто напросто тормозит, как падла, на опрос одного адреса у него может уходить порядка 20-25 секунд (!!!) в независимости от удачного/неудачного коннекта. Посему я бы всё-таки взял что-то от NM, хоть я ихние горбушки и на дух не выношу. Задачка простенькая, думаю, оно того стоит. Удач :)
Цитата:
On 2001-12-15 1020, Разьярённое_x77 wrote
Всё очень просто, только надо учесть, что TClientSocket работает асинхронно. Т.е. конструкции типа
for i = 1 to 255 do begin
ClientSocket1.Host = '192.168.1.' + IntToStr (i);
ClientSocket1.Port = 21;
ClientSocket1.Open;
end;
заставят его просто перебрать все порты, а непосредственно попытка соединения произойдёт только для последнего, что у тебя и твориться. Понимаешь, в момент работы Open ты меняешь адрес и снова вызываешь Open, он, не закончив попытку предыдущего коннекта, лезет на новый, его опять обрывают и т.д. И только самый последний вызов отрабатывает до конца (ошибка - это значит, что коннект невозможен, вот и всё.
Принцп сканирования ClientSocket'ом заключается в том, чтобы, дав команду на соединение, в событиях OnError и OnConnect отреагировать на него (т.е. завершить сканирование, ибо попытаться соединиться со слеующим портом). Выглядит это примерно так (сия прога сканирует локальную сеть с 192.168.1.1 по 192.168.1.255 по 80 порту)
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ScktComp, StdCtrls;
const
First = 1;
Last = 255;
Current integer = First;
Stopped boolean = FALSE;
type
TForm1 = class(TForm)
Button1 TButton;
Memo1 TMemo;
cs TClientSocket;
Button2 TButton;
procedure Button1Click(Sender TObject);
procedure csConnect(Sender TObject; Socket TCustomWinSocket);
procedure csError(Sender TObject; Socket TCustomWinSocket;
ErrorEvent TErrorEvent; var ErrorCode Integer);
procedure Button2Click(Sender TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure ConnectNext;
end;
var
Form1 TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender TObject);
begin
cs.Host = '192.168.1.' + IntToStr (Current);
cs.Port = 80;
Memo1.Lines.Clear;
Stopped = FALSE;
cs.Open;
end;
procedure TForm1.ConnectNext;
begin
if cs.Active then
cs.Close;
if Stopped then
Exit;
Inc (Current);
if Current > Last then
Exit;
cs.Host = '192.168.1.' + IntToStr (Current);
cs.Open;
end;
procedure TForm1.csConnect(Sender TObject; Socket TCustomWinSocket);
begin
Memo1.Lines.Add (Socket.RemoteHost + '(' + Socket.RemoteAddress + ') - Ok!');
ConnectNext;
end;
procedure TForm1.csError(Sender TObject; Socket TCustomWinSocket;
ErrorEvent TErrorEvent; var ErrorCode Integer);
begin
Memo1.Lines.Add (cs.Host + ' - ' + IntToStr (ErrorCode));
ErrorCode = 0;
ConnectNext;
end;
procedure TForm1.Button2Click(Sender TObject);
begin
Stopped = TRUE;
end;
end.
Учти, при этом, что Fantasist, сказав, что ClientSocket "довольно долго пытается соединиться", выразился очень мягко. TClientSocket просто напросто тормозит, как падла, на опрос одного адреса у него может уходить порядка 20-25 секунд (!!!) в независимости от удачного/неудачного коннекта. Посему я бы всё-таки взял что-то от NM, хоть я ихние горбушки и на дух не выношу. Задачка простенькая, думаю, оно того стоит. Удач
Цитата:
On 2001-12-14 1644, Air wrote
Сеществует проблема.
Слушаю порт с помощью ServerSocket.
Хочу чтоб ClientSocket скнировал локальные адреса 192.168.0.0 - 192.168.0.255 чтоб прога увидела сервер.
Как узнать что нет коннекта?
Наверное в событии OnError ClientSocket'а?
Пихаю в цикл попытки коннекта ClientSocket'а, но событие OnError происходит только при выходе из цикла.
Как мне организовать такую штуку?
Например в StarCraft или дугих играх вижу имя сервера (кто создал сетевую игру), потом просто коннекчусь к нему.
Вообще, обычно это не тестируют с помощью соеденения. Существует такая вещь как ping. В виндос входит такая прогаммка, работает в консольном режиме. Как это реализовать прямо сейчас не скажу, но в крайнем случае можно использовать ее перенаправив выходной поток в файл. Правда порты тестирует она исключительно на достижимость адреса, порты она никакие не проверяет.
[ Это Сообщение было отредактировано Fantasist в 2002-03-21 1925 ]
Фигня все это. Есть же компоненты! Если не нравиться NM (мне кстати тоже не нравиться), то есть же компоненты Indy. Наверняка там что-то есть. Хотя я TimeOut я нашел только ы NMPowerSock. Но ведь можно взять PowerSock для тестирования сервера, а затем его убить и соедениться чем-нибудь другим.
Я недавно написал простенькую прогу, которая тоже смотрит, кто есть в сетке (от 10.4.0.1 до 10.4.0.255) и тоже столкнулся с проблемой долгодуманья. Но слава богу, что винда - многозадачная система, я просто создал 255 потоков, в каждом из которых просто сканил заданный адрес. В худшем случае (компов нету) у меня уходило порядка десяти секунд. Если кому надо, могу скинуть исходники на дельфи этой проги или экзешник.