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

Вниз

простейший чат на idTCPServer/idTCPClient   Найти похожие ветки 

 
vers ©   (2004-10-17 16:20) [0]

Для чата будет выделенный сервер и куча клиентов.
Вопрос: для клиента нужно будет оба компонента - idTCPClient (для передачи) и idTCPServer (для приема)? Или как-то можно установить idTCPClient в режиме ожидания входящих сообщений?
Если я все правильно понял, то нельзя.


 
alienserg   (2004-10-18 01:34) [1]

посмотри, как это сделано в примерах Indy (IndyDemos\Chat\Client)


 
vers ©   (2004-10-18 20:27) [2]

хе
там стоит таймер на полсекунды, в нем делается readln с таймаутом 5 мс. то есть, сообщения будут приходить с задержкой максимум 0,5 сек. для меня неприемлима такая задержка, да и не хочу держать потоки открытыми, потому что клиентов предпологается очень много.
пока что остановился на идее ставить каждому клиенту по idTCPServer"у.


 
Rouse_ ©   (2004-10-18 22:22) [3]

> пока что остановился на идее ставить каждому клиенту по
> idTCPServer"у.

Более дурацкой идеи придумать нельзя...
Чем тебе не нравится стандартный механизм?
После момента соединения перестает существовать такое понятие как клиент и сервер... Есть установленное соединение, в оба конца которого ты можешь отправлять и принимать данные...


 
vers ©   (2004-10-19 01:26) [4]

Да, но как это реализовать на TIdTCPClient?
В компоненте TTCPClient есть событие OnReceive, а в TIdTCPClient - нет. Приходится ставить таймер и делать ReadLn с таймаутом. Плюс к этому придется ставить TIdAntiFreeze, чтоб при этом приложение не подвисало. При этом сообщения клиенту будут приходить с дискретностью таймера. Неужели все так и делают? Или есть способ лучше?


 
NAlexey ©   (2004-10-19 16:46) [5]

Отвлеченный вопрос: а почему тебя не устраивает интервал в полсекунды?


 
vers ©   (2004-10-19 16:57) [6]

для чата в локальной сети с интерактивными играми (викторина, мафия и другие) полсекунды - это очень много.


 
NAlexey ©   (2004-10-19 17:11) [7]

ну поставь 100 мсек.


 
vers ©   (2004-10-20 03:33) [8]

Во-первых: что писать в обработчике таймера? ReadLn? А если клиенту пришло 2 сообщения? Тогда второй он получит на втором срабатывании таймера? А если ему 100 строк из буфера отправили? Он их 10 секунд будет получать?
Во-вторых: не люблю открытые соединения. Они грузят проц сервера, да и глюк с ними такой: если комп клиента повис, то соединение ОСТАЕТСЯ ОТКРЫТЫМ. Приходится вводить дополнительную команду ping. А если клиенту придет сообщение после зависания, но до пинга, то вообще глюки начинаются (у меня из-за этого прога-сервер вылетает).
И в-третьих: в клиента, кроме чата планируется встроить мини-файл-сервер, так что самый логичный выход ставить TIdTCPServer.
Если у кого есть замечания, поправьте меня.


 
alienserg   (2004-10-20 15:26) [9]

vers ©   (20.10.04 03:33) [8]

А если ему 100 строк из буфера отправили?
А если ему 100 строк отправили, то делай ReadLn в цикле до первой пустой строки. На время обработки полученного ответа отключай таймер. Обработал принятую команду - снова включай. Больше выдумки и твои проблемы рассосутся.
не люблю открытые соединения.
Не люби. Но твоя затея с серверным компонентом на клиенте для чатовых сообщений имеет изъян: сервер не сможет открыть коннект к такому клиенту для передачи очередного сообщения, если клиент находится под прокси.
Хочешь файл-сервер на клиенте - ставь еще и TIdTCPServer, никто не мешает иметь еще один компонент для специфических задач.
соединение ОСТАЕТСЯ ОТКРЫТЫМ.Приходится вводить дополнительную команду ping.
Обычно пингуют сервер со стороны клиента.
А если клиенту придет сообщение после зависания, но до пинга, то вообще глюки начинаются (у меня из-за этого прога-сервер вылетает).
Не знаю, как у тебя пинг сервера и отправка сообщений организованы, но у меня глюков не наблюдается в такой ситуации.
Плюс к этому придется ставить TIdAntiFreeze
А чем тебе TIdAntiFreeze не нравится? Удобный компонент, снимает основную проблему при блокирующем режиме.


 
Digitman ©   (2004-10-20 15:34) [10]


> vers


значит так ..
немедленно дуй сюда
http://book.itep.ru
читай-вникай до полного просветления в части TCP-протокола и Winsock

ибо то что ты утверждаешь - галиматья


 
JR   (2004-12-20 14:56) [11]

у меня почти такая же проблема.

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
s,sIP,sCommand1,sCommand,sOldNick,sNewNick: string;
i,k:integer;
a:IPNames;
begin
try
sCommand:=AThread.Connection.ReadLn;
sIP:=AThread.Connection.Binding.PeerIP;
If length(sCommand)>0 then
BeGiN
...
...
...
EnD;
except
   begin
   Append(FLogs);
   Writeln(FLogs,"               Exception on Server.Execute "+sIP+": "+sCommand);
   CloseFile(FLogs);
   IdTCPServer1.ThreadMgr.ReleaseThread(AThread);
   end
end;
end;

Иногда чат по полдня бегает без проблем, иногда каждые полчаса виснет.
У меня везде идет запись в логи, и первая ошибка всегда идет отсюда. Потом уже появляются сообщения об ошибках в других местах.

Кому не лень, вышлите, пожалуйста, пример IndyDemos\Chat на jollyrogerrr@yahoo.com.
Я на 6 дельфе сижу, там его нет.


 
Senti   (2005-01-11 13:34) [12]

Что ты мучаешься. Используйте компоненты ICS (http://www.overbyte.be)... Лучше компонентов для работы с сетью не встречал. Indy тоже не плох... но в определенных вещах.
Я довольно много писал под эти компоненты. Можно с легкостью реализовать многопотоковый сервер, который будет прекрасно справлятся с задачами и обрабатывать данные максимально быстро, по мере поступления данных от клиентов.

Я в свое время когда начинал писать свой чат выбирал на какой основе его делать, либо своими руками через API сокеты. Либо использовать готовый компонент. Пришел к выводу, что не стоит изобретать велосипед в этом случае. Перепробовал массу компонентов. И остановился на ICS как наиболее продуманном и удобным в использовании и адаптированию к конкретному проекту. И не жалею.... Компонент просто отличный (это я про TWSocket) и реализацию сокетов от ISC. Тем более в поставке компонента идет масса примеров на все случаи жизни. Кроме того он постоянно обновляется + FWS...


 
Eraser ©   (2005-01-12 01:45) [13]

vers
Не понял вопрос. А зачем idTCPClient ставить в режим ожидания?
Используй idTCPServer, он для этого и сделан!
А все извращения с таймерами приведут к краху твоей программы, когда количество клиентов будет больше двух (или когда какой-нибудь из юзеров забудет на 2 сеунды отпустить Enter при посылке сообщения) по причине рассинхронизации. idTCPServer прекрасно поддерживает многопоточность. Синхронизировать с процедурой-процессором можно одинм мьютексом (событием/критической секцией).


 
Digitman ©   (2005-01-12 17:58) [14]


> для клиента нужно будет оба компонента - idTCPClient (для
> передачи) и idTCPServer (для приема)?


зачем оба-то ? idTCPClient - это кл.часть соединения, idTCPServer - серверная, что следует хотя бы из названия

и та другая части "умеют" и передавать и принимать данные


 
Eraser ©   (2005-01-12 20:44) [15]

Digitman ©
Это само собой!
Я имею ввиду, что чатовские программы обычно не держать открытым TCP соединение, по ряду причин... А инициализировать соединение TCPServer"ом если и можно, то это извращение.


 
vers ©   (2005-01-13 00:34) [16]

Читал book.itep.ru до полного просветления. Просвятился :)
Нашел глюк. Глюк оказался в винде 2003 (или может версия у меня такая глючная). Для проверки ставил другие чаты (ircd, wircd, ircplus2000) - тоже вылетали с той же ошибкой (Access violation по адресу 0000 при чтении очередного сообщения). После того, как перенес чат на WinXP все заработало отлично. Но возник другой вопрос, но это уже в другом топике.


 
Digitman ©   (2005-01-13 08:23) [17]


> Eraser ©   (12.01.05 20:44) [15]


> чатовские программы обычно не держать открытым TCP соединение


как раз строго наоборот - обычно таки держат, ибо под "обычными" чатами (коих туева хуча в сети) подразумеваются чаты, использующие http ... http же есть прикладной протокол, базирующийся на траспортном TCP-протоколе, который подразумевает (!) постоянное соединение между клиентом и сервером


> инициализировать соединение TCPServer"ом если и можно, то
> это извращение


нельзя.


 
vers ©   (2005-01-13 14:01) [18]

>> инициализировать соединение TCPServer"ом если и можно, то
>> это извращение

> нельзя.

можно инициировать соединение от TCPServer"а к серверу :)


 
Digitman ©   (2005-01-13 14:08) [19]


> vers ©   (13.01.05 14:01) [18]


> можно инициировать соединение от TCPServer"а к серверу


имеется ввиду ситуация, когда один TCPServer становится клиентом другого TCPServer ?

чушь.
в штатной реализации это невозможно, ибо либо connect() либо bind()+listen() .. но никак не то и другое одновременно


 
vers ©   (2005-01-13 14:24) [20]

сорри, сглючил :)
посмотрел в исходнике, там программа-сервер создает динамически клиента для коннекта к вышестоящему серверу.


 
Digitman ©   (2005-01-13 14:37) [21]


> vers ©   (13.01.05 14:24) [20]


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


 
Eraser ©   (2005-01-13 16:26) [22]

>>Digitman ©
"обычными" чатами (коих туева хуча в сети) подразумеваются чаты, использующие http ... http же есть прикладной протокол, базирующийся на траспортном TCP-протоколе, который подразумевает (!) постоянное соединение между клиентом и сервером

Действительно- открыл TCPView, у аськи одно соединение established, хотя ещё два порта на прослушке. Всё таки по-моему http чаты не держат TCP соединение открытым... Разве интернет браузер держит открытым соединение, всё время когда открыта какая-либо страница? он загружает все ресурсы и закрывает соединения.

А в этом вопросе, как мне кажется речь идёт о LAN чате, которые редко базируются на http- я не встречал...

vers ©
Динамическое создание клиентов- идеальный вариант, я давно так и делаю. В Indy клиент специально сделан лёгким.


 
vers ©   (2005-01-13 19:08) [23]

я говорил про LAN-чат ессно. :)
тоже делаю динамическое создание idTCPClient.



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

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

Наверх




Память: 0.53 MB
Время: 0.034 c
14-1109313006
вредитель
2005-02-25 09:30
2005.03.20
МРОС (читать заадомм наа пеередд) не дремлет


1-1109846733
Openfire
2005-03-03 13:45
2005.03.20
DBGrid и PageControl


14-1109577722
Чеширский_Кот
2005-02-28 11:02
2005.03.20
Пол Маккартни


8-1102160272
Студент_
2004-12-04 14:37
2005.03.20
Идентичное отображение на принтере


1-1110009333
Гость
2005-03-05 10:55
2005.03.20
Компонент "Object Inspector"