Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как реализовать чтоб сервре и клиент слушали порт? [D7, Win95/98, Win2k, WinXP]


Страницы:   1 2 3

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]

С Антифризом не должно


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо