Текущий архив: 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