![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
простейший чат на idTCPServer/idTCPClient [D7, WinXP]
vers © (2004-10-17 16:20:00)Для чата будет выделенный сервер и куча клиентов.
Вопрос: для клиента нужно будет оба компонента - idTCPClient (для передачи) и idTCPServer (для приема)? Или как-то можно установить idTCPClient в режиме ожидания входящих сообщений?
Если я все правильно понял, то нельзя.
vers (2005-01-13 19:08:00) [1]я говорил про LAN-чат ессно. :)
тоже делаю динамическое создание idTCPClient.
Eraser (2005-01-13 16:26:00) [2]>>Digitman ©
"обычными" чатами (коих туева хуча в сети) подразумеваются чаты, использующие http ... http же есть прикладной протокол, базирующийся на траспортном TCP-протоколе, который подразумевает (!) постоянное соединение между клиентом и сервером
Действительно- открыл TCPView, у аськи одно соединение established, хотя ещё два порта на прослушке. Всё таки по-моему http чаты не держат TCP соединение открытым... Разве интернет браузер держит открытым соединение, всё время когда открыта какая-либо страница? он загружает все ресурсы и закрывает соединения.
А в этом вопросе, как мне кажется речь идёт о LAN чате, которые редко базируются на http- я не встречал...
vers ©
Динамическое создание клиентов- идеальный вариант, я давно так и делаю. В Indy клиент специально сделан лёгким.
Digitman (2005-01-13 14:37:00) [3]
> vers © (13.01.05 14:24) [20]
во !
эт совсем другой коленкор)
и как раз из этого коленкора пошиты чуть ли не все приложения, реализующие хотя бы ф-ции того же прокси-сервера
vers (2005-01-13 14:24:00) [4]сорри, сглючил :)
посмотрел в исходнике, там программа-сервер создает динамически клиента для коннекта к вышестоящему серверу.
Digitman (2005-01-13 14:08:00) [5]
> vers © (13.01.05 14:01) [18]
> можно инициировать соединение от TCPServer'а к серверу
имеется ввиду ситуация, когда один TCPServer становится клиентом другого TCPServer ?
чушь.
в штатной реализации это невозможно, ибо либо connect() либо bind()+listen() .. но никак не то и другое одновременно
vers (2005-01-13 14:01:00) [6]>> инициализировать соединение TCPServer'ом если и можно, то
>> это извращение
> нельзя.
можно инициировать соединение от TCPServer'а к серверу :)
Digitman (2005-01-13 08:23:00) [7]
> Eraser © (12.01.05 20:44) [15]
> чатовские программы обычно не держать открытым TCP соединение
как раз строго наоборот - обычно таки держат, ибо под "обычными" чатами (коих туева хуча в сети) подразумеваются чаты, использующие http ... http же есть прикладной протокол, базирующийся на траспортном TCP-протоколе, который подразумевает (!) постоянное соединение между клиентом и сервером
> инициализировать соединение TCPServer'ом если и можно, то
> это извращение
нельзя.
vers (2005-01-13 00:34:00) [8]Читал book.itep.ru до полного просветления. Просвятился :)
Нашел глюк. Глюк оказался в винде 2003 (или может версия у меня такая глючная). Для проверки ставил другие чаты (ircd, wircd, ircplus2000) - тоже вылетали с той же ошибкой (Access violation по адресу 0000 при чтении очередного сообщения). После того, как перенес чат на WinXP все заработало отлично. Но возник другой вопрос, но это уже в другом топике.
Eraser (2005-01-12 20:44:00) [9]Digitman ©
Это само собой!
Я имею ввиду, что чатовские программы обычно не держать открытым TCP соединение, по ряду причин... А инициализировать соединение TCPServer'ом если и можно, то это извращение.
Digitman (2005-01-12 17:58:00) [10]
> для клиента нужно будет оба компонента - idTCPClient (для
> передачи) и idTCPServer (для приема)?
зачем оба-то ? idTCPClient - это кл.часть соединения, idTCPServer - серверная, что следует хотя бы из названия
и та другая части "умеют" и передавать и принимать данные
Eraser (2005-01-12 01:45:00) [11]vers
Не понял вопрос. А зачем idTCPClient ставить в режим ожидания?
Используй idTCPServer, он для этого и сделан!
А все извращения с таймерами приведут к краху твоей программы, когда количество клиентов будет больше двух (или когда какой-нибудь из юзеров забудет на 2 сеунды отпустить Enter при посылке сообщения) по причине рассинхронизации. idTCPServer прекрасно поддерживает многопоточность. Синхронизировать с процедурой-процессором можно одинм мьютексом (событием/критической секцией).
Senti (2005-01-11 13:34:00) [12]Что ты мучаешься. Используйте компоненты ICS ( http://www.overbyte.be)... Лучше компонентов для работы с сетью не встречал. Indy тоже не плох... но в определенных вещах.
Я довольно много писал под эти компоненты. Можно с легкостью реализовать многопотоковый сервер, который будет прекрасно справлятся с задачами и обрабатывать данные максимально быстро, по мере поступления данных от клиентов.
Я в свое время когда начинал писать свой чат выбирал на какой основе его делать, либо своими руками через API сокеты. Либо использовать готовый компонент. Пришел к выводу, что не стоит изобретать велосипед в этом случае. Перепробовал массу компонентов. И остановился на ICS как наиболее продуманном и удобным в использовании и адаптированию к конкретному проекту. И не жалею.... Компонент просто отличный (это я про TWSocket) и реализацию сокетов от ISC. Тем более в поставке компонента идет масса примеров на все случаи жизни. Кроме того он постоянно обновляется + FWS...
JR (2004-12-20 14:56:00) [13]у меня почти такая же проблема.
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 дельфе сижу, там его нет.
Digitman (2004-10-20 15:34:00) [14]
> vers
значит так ..
немедленно дуй сюда
http://book.itep.ru
читай-вникай до полного просветления в части TCP-протокола и Winsock
ибо то что ты утверждаешь - галиматья
alienserg (2004-10-20 15:26:00) [15]vers © (20.10.04 03:33) [8]
А если ему 100 строк из буфера отправили?
А если ему 100 строк отправили, то делай ReadLn в цикле до первой пустой строки. На время обработки полученного ответа отключай таймер. Обработал принятую команду - снова включай. Больше выдумки и твои проблемы рассосутся.
не люблю открытые соединения.
Не люби. Но твоя затея с серверным компонентом на клиенте для чатовых сообщений имеет изъян: сервер не сможет открыть коннект к такому клиенту для передачи очередного сообщения, если клиент находится под прокси.
Хочешь файл-сервер на клиенте - ставь еще и TIdTCPServer, никто не мешает иметь еще один компонент для специфических задач.
соединение ОСТАЕТСЯ ОТКРЫТЫМ.Приходится вводить дополнительную команду ping.
Обычно пингуют сервер со стороны клиента.
А если клиенту придет сообщение после зависания, но до пинга, то вообще глюки начинаются (у меня из-за этого прога-сервер вылетает).
Не знаю, как у тебя пинг сервера и отправка сообщений организованы, но у меня глюков не наблюдается в такой ситуации.
Плюс к этому придется ставить TIdAntiFreeze
А чем тебе TIdAntiFreeze не нравится? Удобный компонент, снимает основную проблему при блокирующем режиме.
vers (2004-10-20 03:33:00) [16]Во-первых: что писать в обработчике таймера? ReadLn? А если клиенту пришло 2 сообщения? Тогда второй он получит на втором срабатывании таймера? А если ему 100 строк из буфера отправили? Он их 10 секунд будет получать?
Во-вторых: не люблю открытые соединения. Они грузят проц сервера, да и глюк с ними такой: если комп клиента повис, то соединение ОСТАЕТСЯ ОТКРЫТЫМ. Приходится вводить дополнительную команду ping. А если клиенту придет сообщение после зависания, но до пинга, то вообще глюки начинаются (у меня из-за этого прога-сервер вылетает).
И в-третьих: в клиента, кроме чата планируется встроить мини-файл-сервер, так что самый логичный выход ставить TIdTCPServer.
Если у кого есть замечания, поправьте меня.
NAlexey (2004-10-19 17:11:00) [17]ну поставь 100 мсек.
vers (2004-10-19 16:57:00) [18]для чата в локальной сети с интерактивными играми (викторина, мафия и другие) полсекунды - это очень много.
NAlexey (2004-10-19 16:46:00) [19]Отвлеченный вопрос: а почему тебя не устраивает интервал в полсекунды?
vers (2004-10-19 01:26:00) [20]Да, но как это реализовать на TIdTCPClient?
В компоненте TTCPClient есть событие OnReceive, а в TIdTCPClient - нет. Приходится ставить таймер и делать ReadLn с таймаутом. Плюс к этому придется ставить TIdAntiFreeze, чтоб при этом приложение не подвисало. При этом сообщения клиенту будут приходить с дискретностью таймера. Неужели все так и делают? Или есть способ лучше?