![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как реализовать чтоб сервре и клиент слушали порт? [D7, Win95/98, Win2k, WinXP]
h0use © (2003-11-25 17:14:00)
Есть сервак, у которого в методе OnExecute
procedure TFM.TCPServerExecute(AThread: TIdPeerThread);
var
AMsg : TCommBlock;
Msg : String;
begin
if not AThread.Terminated and AThread.Connection.Connected then
try
Msg:=AThread.Connection.ReadLn;
if Msg="" then exit;
AThread.Connection.ReadBuffer(AMsg,SizeOf(AMsg));
ShowMessage(IntToStr(AMsg.Command)+IntToStr(AMsg.Argument1)+IntToStr(AMsg.Argument2)+AMsg.Msg);
case AMsg.Command of //
cmdLogin : ServerLogin(AMsg,AThread);
cmdLogout : ServerLogout(AMsg,AThread);
cmdCommand: ServerCommand(AMsg,AThread);
cmdSQL : ServerSQL(AMsg,AThread);
cmdMessage: ServerChat(AMsg,AThread);
end; // case
except
on E: Exception do
SaveLog(0,3,"Socket read error: " + e.Message);
end;
end; // TCPServerExecute
Работает и сам сервак не виснет, но в клиенте в процедуре
procedure TfmMain.TimerTimer(Sender: TObject);
var
AMsg: TCommBlock;
Msg : String;
begin
if (not TCPClient.Connected) then exit;
try
Msg:=TCPClient.ReadLn(#10,50); <------------- Вот здесь висим после первого обмена информацией
if Msg="<<<" then
begin
TCPClient.ReadBuffer(AMsg,SizeOf(AMsg));
case AMsg.Command of //
cmdLogin : ClientConnect(AMsg);
cmdLogout: ClientDisconnect(AMsg);
end; // case
end;
except
on e: Exception do
ShowMessage(e.Message);
end; // try/except
Application.ProcessMessages;
end;
Как сделать так, чтоб клиент при ожидании какой-либо инфы от сервера не вис?
h0use (2003-11-26 17:58:00) [1]
Разобрался, всем спасибо! Огромное!
h0use (2003-11-26 17:50:00) [2]
Теперь другая ботва, два колиента на одной машине запускаются нормалльно, но при запуске третьего клиента, перд. два виснут.
Reindeer Moss Eater (2003-11-26 16:51:00) [3]
Ну дык сделай запись глобальной переменной и откажись от передачи указателей в параметрах сообщения вообще.
h0use (2003-11-26 16:46:00) [4]
> Reindeer Moss Eater
> при работе через указатель на запись читается не то, что
> хочется
Именно это!
procedure TfmMain.OnServerMessage(var Msg : TMessage);
var
AMsg:TCommBlock;
PMsg:PCommBlock;
begin
PMsg:=PCommBlock(Msg.WParam);
AMsg:=PMsg^;
case AMsg.Command of //
cmdLogin : ClientConnect(AMsg);
cmdLogout: ClientDisconnect(AMsg);
end; // case
end; //
в AMsg пишется полный бред. А когда было простоPCommBlock(Msg.WParam).Commandпердовалось не значение, а непонятное число (есть мнение, что адрес).
Reindeer Moss Eater (2003-11-26 16:30:00) [5]
Digitman
Конечно заметано.
Только ничего и не было.
Я просто не хотел показаться агентом по продаже антифриза.
Digitman (2003-11-26 16:24:00) [6]
> Reindeer Moss Eater
заметано)
было просто мнение, высказанное вслух ... более безадресно, нежели иначе
я, как ты знаешь, не пользую Инди из принципа (кому - как, согласен и на "из дурацкого")
по назойливому сабжу сразу беру Инди-исходники и, как правило, вижу там большую задницу... об чем и не сдержался высказать свое "фи !")
Ok ?
Reindeer Moss Eater (2003-11-26 16:14:00) [7]
В полях записи нет данных, или при работе через указатель на запись читается не то, что хочется?
h0use (2003-11-26 16:07:00) [8]
миролюбивоМальчики, не деритесь и не спорте, для моего простенького клиента с одним кодовым потоком за глаза, это мой первый опыт с сервером и клиентом и с Инди и с потоками, так что зачем мудрить, мне пока Антифриза "за глаза" хватает.
Может много уважаемый RME все же обратит свой взор на мелкого червя Хауса, дабы объяснить, как в его процедуре получить значения полей записи в обработчике сообщения?
Reindeer Moss Eater (2003-11-26 16:00:00) [9]
Digitman ©
Все выглядит так, как будто я веду себя как тот парень с тайдом и кипячением.
Я рекомендовал использовать его хаусу исключительно из соображений быстроты достижения результата.
Digitman (2003-11-26 15:56:00) [10]
> Reindeer Moss Eater
весь смысл этого "антифриза" сводится до избавления ленивого и нерадивого "батонокидателя" от необходимости явно и полностью подконтрольно вызывать в тех или иных местах алгоритма пресловутый Application.ProcessMessages
кр.того, VCL недопускает такого вызова в доп.код.потоке, посему "фоновое" применение "антифриза" в доп.код.потоке без синхронизации с осн.код.потоком приведет к печальным последствиям
да и по-любому - механизм "антифриза" оправдан и должен имееть смысл для ЛЮБОГО код.потока, выполнение которого блокируется длительными блок.операциями, а не только основного) ... ведь доп.код.поток так же как и основной имеет полное право получать и реагировать на сообщения, адресованные конкретно ему !
h0use (2003-11-26 15:48:00) [11]
У меня в
PMyServerCmd(Msg.WParam).sc_Cmd_Typeпередается какая-то белеберда, совсем не то что сервак послал! Как получить реальное значение?
Digitman (2003-11-26 15:47:00) [12]
> sanya-spb
> Reindeer Moss Eater © (26.11.03 15:38) [46]
> то вызывается DoProcess
вот-вот) ... в этом и вся соль : чтобы этот самый DoProcess() эпизодически вызывался, нужно чтобы осн.код.поток процесса не "висел" неопределенное время на выполнении блокирующей ф-ции ... а для этого в блок.режиме как раз и фигурируют тайм-ауты ... которые , как показывает практика, многие расставляют попросту "от балды" при вызове блок.ф-ций чтения/записи
Reindeer Moss Eater (2003-11-26 15:38:00) [13]
- антифриз этот хваленый работает в том же код.потоке, что и TCPClient, т.е. - синхронно ... толку от него - почти ноль
И что из этого?
Заглянем внутрь реализации синхронного метода и увидим полет мысли авторов библиотеки. Если пользователь хочет что бы сообщения Windows продожали обрабатываться, то вызывается DoProcess в котором делается Application.Processmesages. Если юзер этого не хочет, этого не делается.
Digitman (2003-11-26 15:35:00) [14]
> sanya-spb
вопрос про тайм-ауты тесно связан с механизмом гнезд Winsock, инициализированных для работы в блокирующем (синхронном) режиме
следы использования тайм-аутов ожидания ведут прямиком к как минимум ф-ции Winsock select() (она явно используется при работе TCPClient)
почитай для начала описание этой ф-ции
sanya-spb (2003-11-26 15:10:00) [15]секундочку.... а теперь если можно поподробнее про малые таймауты ожидания и что делать если они не являются таковыми??
в продолжение моего вопроса
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1069680032&n=4
чувствую что тут кроется ответ на мой вопрос...
h0use (2003-11-26 15:09:00) [16]
Это я уже сам разобрал. Антифриз как ни странно помогает, сейчас я Рейндировский код адаптировал под себя, вроде все работает, только дисконнект не распознает, зато теперь не висит, и вроде проц не грузит. Так что решение с связкой Антифриза и сообщений весьма рабоче. С Thread пока опасаюсь связываться, так как не совсем подкован в этом вопросе.
Digitman (2003-11-26 14:44:00) [17]
> h0use © (26.11.03 14:08) [41]
наврал я тебе
никакой OnWork тебе не поможет
и антифриз - тоже не панацея
тебя спасут только ИЛИ малые таймауты ожидания ИЛИ вынос всего этого трансп.хозяйства в доп.код.поток (причем и там весьма нежелательно ставить большие таймауты)
только что посмотрел в исходники :
- TidTCPClient работает искл-но в блок.режиме
- антифриз этот хваленый работает в том же код.потоке, что и TCPClient, т.е. - синхронно ... толку от него - почти ноль
h0use (2003-11-26 14:08:00) [18]
Поставил обработку:
procedure TfmMain.TCPClientWork(Sender: TObject; AWorkMode: TWorkMode;
const AWorkCount: Integer);
begin
if AWorkMode=wmRead then ShowMessage("Ku-ku");
end;
при любом сообщении с сервера ничего не происходит!
Digitman (2003-11-26 13:57:00) [19]
> Reindeer Moss Eater © (26.11.03 13:46) [39]
LOL
> h0use © (26.11.03 13:46) [38]
нафига ?! ну нафига тебе, скажи на милось, всякие таймеры да антифризы ? если есть событие OnWork(), АСИНХРОННО извещающее тебя о наступлении сетевого транспортного события а-ля "сервер ан сей момент прислал N байт, можно безо всяких задержек прочитать эти N байт из буфера и передать их на обработку куда-то" ?
h0use (2003-11-26 13:46:00) [20]
С Антифризом не должно