Форум: "Сети";
Текущий архив: 2002.12.16;
Скачать: [xml.tar.bz2];
ВнизКак работать с TServerSocket используя режим ThreadBlocking? Найти похожие ветки
← →
User911? (2002-09-18 13:37) [0]Хочу написать простейшую проксю и не могу разобраться с принципом работы TServerSocket в режиме TheadBlocking он порождает некий поток, так вот как с ним работать (всмысле чтоб в потоке мой код исполнялся, то есть создавалось соединение и так далее....
← →
Digitman (2002-09-18 15:00) [1]читаем хэлп на событие OnGetThread():
Occurs when the server socket needs to create a new execution thread for a connection to a client socket.
type
TGetThreadEvent = procedure (Sender: TObject; ClientSocket: TServerClientWinSocket; var SocketThread: TServerClientThread) of object;
property OnGetThread: TGetThreadEvent;
Description
Write an OnGetThread event handler to create a specialized descendant of TServerClientThread for the connection to the client socket. Create the new thread with the CreateSuspended parameter set to False, and return it in the SocketThread parameter. OnGetThread only occurs if there are no idle threads in the cache.
Most applications that use thread-blocking connections will want to create a new descendant of TServerClientThread in an OnGetThread event handler. This is because the default behavior of TServerClientThread uses the OnClientRead and OnClientWrite event handlers for reading and writing. These events occur on the server socket, which is not thread-local.
The Sender parameter is the TServerWinSocket object that received the client request. The ClientSocket parameter is the TServerClientWinSocket object that will communicate with the client socket.
Note: The OnGetThread event handler for TServerWinSocket is also set when setting the OnGetThread event handler of the associated TServerSocket.
Что тебе здесь непонятно ? И не рановато ль за прокси взялся ты ?
← →
User911? (2002-09-18 17:01) [2]Я конечно понимаю, что рановато... проще конечно где-нибудь поискать нормальную проксю, которая все умеет, тока я таких мало видел (может что кто посоветует из проксов (WinProxy и подобную ерунду не предлагать... :))
Просто с потоками пока еще не совсем дружу. Если не влом, объясните по-человечески где мне написать нечто ниже следующее и как подставить чтоб это выполнялось при каждом клиентском коннекте???
Вот типа оно (нижеследующее :)
procedure ...
begin
Соединяюсь со внешней проксей...
Перекидываю ему все что пришло...
Все от нее принимаю...
Передаю присоединившемуся ко мне клиенту...
// По возможности среди этог всего будет что-то вроде кэша.
end.
Если это гиблый путь, так и скажите..........
← →
{bas} (2002-09-18 17:16) [3]я сделал так
http://delphi.mastak.ru/cgi-bin/forum.pl?look=1&id=1031143686&n=4
но чего несовсем работает - ошибки выскакивают, никак от них не могу избавится. Если чего-то получится нормальное - пиши прямо в форум
← →
Polevi (2002-09-18 17:29) [4]работай лучше асинхронно - вот тебе пример, учти что тут все упрощенно, нет обработки ошибок, на деле все сложнее
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ScktComp;
type
TClient=class(TClientSocket)
public
FAcceptSocket:TCustomWinSocket;
constructor Create(ASocket:TCustomWinSocket);reintroduce;
procedure Do_Read(Sender: TObject; Socket: TCustomWinSocket);
end;
type
TForm1 = class(TForm)
ss: TServerSocket;
procedure ssAccept(Sender: TObject;
Socket: TCustomWinSocket);
procedure FormCreate(Sender: TObject);
procedure ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
ss.Port:=666; //слушаем
ss.Active:=true;
end;
procedure TForm1.ssAccept(Sender: TObject;
Socket: TCustomWinSocket);
var
client:TClient;
begin
client:=TClient.Create(Socket);
client.Address:="192.168.1.3"; //вот сюда хотим
client.Port:=110; //подключиться
Socket.Data:=client;
client.Active:=true;
end;
procedure TForm1.ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
Buf:Pointer;
BytesRead:DWORD;
begin
BytesRead:=Socket.ReceiveLength;
GetMem(Buf,BytesRead);
Socket.ReceiveBuf(Buf^,BytesRead);
TClient(Socket.Data).Socket.SendBuf(Buf^,BytesRead);
end;
{ TClient }
constructor TClient.Create(ASocket: TCustomWinSocket);
begin
inherited Create(nil);
FAcceptSocket:=ASocket;
OnRead:=Do_Read;
end;
procedure TClient.Do_Read(Sender: TObject; Socket: TCustomWinSocket);
var
Buf:Pointer;
BytesRead:DWORD;
begin
BytesRead:=Socket.ReceiveLength;
GetMem(Buf,BytesRead);
Socket.ReceiveBuf(Buf^,BytesRead);
FAcceptSocket.SendBuf(Buf^,BytesRead);
end;
← →
Deeps (2002-09-18 17:43) [5]Но полеви крут! учитесь =)
← →
Digitman (2002-09-18 18:09) [6]>User911
> Я конечно понимаю, что рановато... проще конечно где-нибудь
> поискать нормальную проксю, которая все умеет, тока я таких
> мало видел (может что кто посоветует из проксов (WinProxy
> и подобную ерунду не предлагать... :))
>
К примеру, WinRoute v4.x - вполне сносное, достаточно надежное и много чего "умеющее" ПО.
> Просто с потоками пока еще не совсем дружу. Если не влом,
> объясните по-человечески где мне написать нечто ниже следующее
> и как подставить чтоб это выполнялось при каждом клиентском
> коннекте???
Если "не дружишь" - не берись пока за них (за потоки), пытаясь сразу же "присобачить" их к не менее мудреной прокси-логике. Лучше поизучай и потренируйся на простенькой задачке, типа той, что реализована в демо-проекте threads.dpr.
Гнездовой транспорт же изучай пока на stNonBlocking-сервере, как советует <Polevi>. Это совершенно иная, непересекающаяся задача, тонкости которой вполне можно освоить и без всяких "потоков".
Убедившись, что обе большинство аспектов обеих задач достаточно понимаемы тобой, начинай соединять их воедино : принципы/логику мультипоточных выфчислений в процессе и принципы/логику транспорта с использованием гнезд.
Только так ты сможешь подойти к этапу, на котором настоящая сквозная прокси-логика станет для тебя вполне понятной и реализуемой в коде
← →
User911? (2002-09-19 12:57) [7]2Digitman:
WinRoute - рутер, а не прокся. Стоит... юзаю... рутер классный, а прокси глюкавый, FTP через него вообще криво работает, да и с кэшем траблы проскальзывают... хочу отдельный маленький нормальный прокси..... во как.
Ну а за советы спасибо...
2Polevi:
Спасибо за код... доработаем... пропарсим все входящее... и может кэш прикрутим...
← →
User911? (2002-09-19 13:02) [8]2Polevi:
Только вопрос, а что будет если еще один клиент ко мне приконнектится и в OnAccept"е получу я еще раз client:=TClient.Create(Socket);
и что тогда???
← →
Digitman (2002-09-19 13:14) [9]>User911
Рутер, не рутер) ... Нормальное ПО) ... При таких познаниях тебе и такого не написать. Прислушайся-таки к совету - не старайся сразу сколь-либо серьезный продукт написать, начни с малого - дели задачу на автономные подзадачи и сориентируйся в каждой из них детально. Не лепи в одну кучу транспорт, мультипоточность и прокси-логику - ничего путного не получится, если в каждой их этих подзадач ты "плаваешь", уверяю тебя !
← →
Polevi (2002-09-19 13:54) [10]>и что тогда???
создается еще один экз. TClient - что конкретно непонятно то ?
← →
User911? (2002-09-20 13:05) [11]>>и что тогда???
>создается еще один экз. TClient - что конкретно непонятно то ?
так вот и не понятно - как это все работать будет. На картинке все изумительно, а кто эти экземпляры освождать будет и прочее, там память, например.
Специально протестил это все и... с одним подключением есесьенно все работает, а два.. три... и все впадает в незаканчивающийся транс........... как это можно объяснить ???
← →
Anatoly Podgoretsky (2002-09-20 13:13) [12]Это все последствия в отсутствии знаний и сразу за серьезную задачу, может чего попроще для начала, а по мере роста знаний можно и посложнее.
← →
User911? (2002-09-20 20:30) [13]2Anatoly Podgoretsky Спасибо... утешил!
← →
VitasS (2002-09-20 22:19) [14]Если вам не вломно подскажите (ответ на почту), как можно не
используя формы и наворотов ДЕЛЬФИ только через API написать
клиент или сервер! Например сервер почты или сервер новостей! Где взять набор команд точнее описание! Если не вломно полное описание соединения Блоки, НОН-Блоки ТнериаКоннект. Приглашаются пользователи хорошо знающие сети для сотрудн7ичества в новом проэкте. Если можно код только для API или c набором стндартных процедур Win9x.
← →
Andrey Klimov (2002-10-18 13:47) [15]http://17slon.com/gp/gp/tgphttpproxy.htm
Один недостаток на момент опубликования - редирект работает только для хоста, для хоста с путем не работает.
А так, очень даже то, что Вы желаете.
Кстати, может доработаете чтобы редирект для хоста с путем работал, тогда цены этой компоненте не будет...:)
← →
Digitman (2002-10-18 14:23) [16]>VitasS
Если вам не вломно подскажите (ответ на почту), как можно не
используя формы и наворотов ДЕЛЬФИ только через API написать
клиент или сервер!
А зачем "через API" ? Чем тебе "навороты ДЕЛЬФИ" не нравятся ? Чем оправдано такое неприятие ?
Где взять набор команд точнее описание!
"набор команд" чего ? "описание" чего ?
Блоки, НОН-Блоки ТнериаКоннект.
Это из какой оперы ? Где ты почерпнул эти термины ? Особенно - "ТнериаКоннект" ?
Приглашаются пользователи хорошо знающие сети для сотрудн7ичества в новом проэкте.
Это тебе - в "Потрепаться". К <Николаю Быкову>. У него имеется "опыт" ангажирования. Пароль не забудь сказать - "DiamondSoft" ...)
Если можно код только для API или c набором стндартных процедур Win9x
код чего ? для API чего ?
набором стндартных процедур Win9x
Нет такого. Есть Win32API - интерфейс программирования приложений в операционной среде, базирующейся на платформе Win32. Оригинальный источник информации - http://msdn.microsoft.com
← →
VID (2002-10-18 19:39) [17]TO USER911:
что бы не потерять всех TClient делай так:
объяви глобальные объект ClientList:TStringList;
там где написано Client:=TClient.Create(..); добавь след-ей строкой:
ClientList.AddObject(IntToStr(Client.FAcceptSocket.SocketHandle), Client);
В списке ClientList у тебя будут храниться ссылки на все созданные объекты типа TClient.
Удалять их можно так:
1. создаёшь функцию
Function DeleteClient(var ASocket:TCustomWinSocket);
Var I:Integer;
Client:TClient;
begin
I:=-1;
REPEAT
Inc(I);
IF ClientList.Objects[I] is TClient then
IF (ClientList.Objects[I] as TClient).FAcceptSocket = ASocket then
begin
Client:=(ClientList.Objects[I] as TClient);
ClientList.Delete(I);
FreeAndNil(Client);
Result := True;
Exit;
end;
UNTIL (I>=ClientList.Count-1);
RESULT := FALSE;
end;
2. В событиях onClientDisconnect и onClientError пишешь:
begin
DeleteClient(Socket);
FreeAndNil(Socket); //Эта строка - последнаяя в указанных обработчиках
end;
← →
VID (2002-10-18 19:42) [18]а вообще создание stNonBlocking сервера - утопия, на собственном опыте знаю...
← →
Polevi (2002-10-20 13:14) [19]2VID © (18.10.02 19:42)
если руки кривые все утопия
← →
VID (2002-10-20 14:24) [20]to Polevi: Что ж.. может у тебя руки и прямее моих, но и я со своими кривыми руками, смогу ввести такой stNonBlocking сервер в состояние нирваны.
Конечно, если этот сервер будет работать в условиях, "где все хорошие", то можно смело делать такой сервер. Ну а если найдётся "славный парень" который решит законнектить на этот сервер 5000 или больше клиентов, и каждый из них будет ещё что-то отправлять на сервер... Механизмы безопасности этого сервера ДАЖЕ НЕ БУДУТ РАБОТАТЬ.
вот тебе и утопия.
← →
Digitman (2002-10-20 14:39) [21]>>Механизмы безопасности этого сервера ДАЖЕ НЕ БУДУТ РАБОТАТЬ
Ерунда полная. Какое отношение к режиму работы гнездовых транспортных ф-ций имеет какой-то там "механизм безопасности" - совершенно непонятно.
← →
Polevi (2002-10-20 19:56) [22]2VID © (20.10.02 14:24)
как раз в твоем любимом блочном режиме 5000 потоков просто сожрут все адресное пространство
надо самому проверять к примеру сколько от одного IP клиентов и килять и заносить в черный список, если что
← →
VID (2002-10-21 00:07) [23]to polevi: вот как раз все эти "килять", и "заносить в чёрный список" я и называю "механизмом безопасности".
а в твоём любимом неблок. режиме, ОН ДАЖЕ НА СТАНЕТ РАБОТАТЬ, просто потому что сервер заблокирует весь основной поток, своими onClientConnect, onClientRead, onClientError и onclientDisconnect.
сервер-приложение просто будет выглядеть повисшим...
← →
Polevi (2002-10-21 09:07) [24]давай продолжим разговор через годик, когда ты поумнеешь, ok ?
без обид
← →
Digitman (2002-10-21 10:27) [25]>VID
В том виде, в каком реализован TServerWinSocket, ни о каком нормальном "механизме безопасности" не может идти и речи.
Даже если ты вычислил спаммера, ты не сможешь заставить сервер отвергать попытки коннекта со стороны этого клиента - на любой корректный запрос коннекта (корректный SYN-пакет) сервер всегда ответит подтверждением готовности к коннекту (SYN-ACK-пакет) и создаст на своей стороне отдельное гнездо (читай - ресурс для спам-клиента сервером будет безусловно выделен).
Если же подходить к задаче с полным пониманием дела, то нужно знать, что серверное гнездо "умеет" поступать и по-иному : в ответ на SYN-пакет клиента можно возвратить и RST-пакет, который при получении будет интерпретирован клиентом как reject (отвержение запроса на соединение), что фактически для спамера будет выглядеть как "отказ в обслуживании" (тот же отказ, что и получаемый клиентом при недоступности целевого хоста/сервиса).
Иными словами , существует спец.механизм - механизм условного акцепта сервером вх.запросов клиентов на соединение.
В Winsock2 он базируется на двух "китах" :
- спец.опция "слушающего" гнезда SO_CONDITIONAL_ACCEPT
- альтернативная ф-ция Winsock2.WSAAccept
Механизм условного акцепта работает только в Winsock2 под управлением W2k/XP.
Видимо Борланд ради совместимости с Win9x и NT счел ненужным задействование данного механизма в своих штатных серверных компонентах. Но при желании и осознанной необходимости вполне можно и переделать/доработать эти компоненты для задействования механизма условного акцепта. И вот только тогда можно с полной серьезностью и знанием дела рассуждать о действительной реализации сервером некоего "механизма безопасности" в части блокировки попыток коннекта со стороны нежелательных клиентов.
P.S. Следует еще раз подчеркнуть, что блокирующий и неблокирующий режимы работы транспортно-диспетчерских ф-ций Winsock (равно как и Делфи-компонентов, инкапсулирующих Winsock-вызовы) не имеет ничего общего с механизмом условного акцепта
← →
VID (2002-10-21 23:26) [26]TO DIGITMAN: Спасибо за эту информацию.
TO POLEVI: Что-то мне подсказывает, что и через годик, когда я поумнею, мы с тобой не сможем конструктивно продолжить этот разговор... так что всё.
← →
Polevi (2002-10-22 09:30) [27]2VID © (21.10.02 23:26)
сохрани эту ветку и через годик прочти
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2002.12.16;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.01 c