Форум: "Сети";
Текущий архив: 2003.10.09;
Скачать: [xml.tar.bz2];
ВнизЧаты без сокетов Найти похожие ветки
← →
Doctor Deejay (2003-08-07 15:26) [0]Помогите мне разобраться.... Каким образом работают чаты, у которых нет разделения между кллиентской частью и серверной??? Где-то слышал, что это UDP.
Подскажите, если кто знает. Может статья где-то есть. Как оно работает???
Или скелет такого чата(без наворотов), который показал бы принцип работы.....
← →
Erik Ivanov (2003-08-07 16:52) [1]Бери Indy и смотри примеры.
← →
Rouse_ (2003-08-07 17:07) [2]Принцип прост: Каждый из чатов является сервером UDP, общаются между собой чаты отправкой широковещательных пакетов, в просторечии броадкастов.
Желаю успехов
← →
Doctor Deejay (2003-08-08 01:55) [3]
> Rouse_ © ( 07.08.03 16:52)
> Rouse_ ©
А как чат у одного человека может знать, где запущена еще копия? Диапазон всех IP в мире не такой и маленький, чтобы все опрашивать по какому-то порту... :?
> Erik Ivanov (07.08.03 16:52)
> Бери Indy и смотри примеры.
Они есть в 6 Делфи. Какой именно компонент?
← →
Rouse_ (2003-08-08 02:19) [4]> Диапазон всех IP в мире не такой и маленький
Вам так кажется.
Первое: идет ограничение маской подсети
Второе идет ограничение по адресу
К примеру, не обязательно (при соответствующих настройках) что броадкаст с адреса 192.0.0.1 дойдет до адреса 192.0.1.1 (в моей домашней сети доходит только каждый четвертый - шестой пакет).
А вот на адрес 192.0.0.243 - пакет придет обязательно.
Желаю успехов
ЗЫ: Да, а при чем тут мир?
ЗЗЫ: TIdUDPClient, TIdUDPServer + (желательно прописать в uses: IdSocketHandle)
← →
Doctor Deejay (2003-08-08 11:06) [5]
> ЗЫ: Да, а при чем тут мир?
Хочу сделать чат, в котором моглы бы общеться люди с разных городов, но без html и тормознутых обновлений...
Тогда может подскажете мысль???
У меня была идея сделать ответный модуль на php, но я в нем не так силен. Этот модуль и был бы серверов.
Есть еще способ закидывать мессаги на какой-то сайт, а потом заставлять всех их оттуда читать.. Но там только с обновлением... :(
← →
servs (2003-08-08 11:20) [6]По протоколу Аськи не лучше?
ИМХО peer2peer чаты есть смысл юзать только в локалке.
← →
Rouse_ (2003-08-08 11:53) [7]Ёёё, ну а кто Вам сказал что такие чаты не имеют выделенной серверной части? Я думал, что речь идет о локальном чате. И использование UDP нецелесообразно для таких вещей. А если в PHP не сильны, то посмотрите статьи по написании WEB приложений средствами Delphi. Они были и на нашем сайте и на Королевстве.
Желаю успехов
← →
Doctor Deejay (2003-08-09 00:46) [8]
> А если в PHP не сильны, то посмотрите статьи по написании
> WEB приложений средствами Delphi
Это всё хорошо, но найти хостинг на котором сервак под виндой так же сложно, как и придумать способ создания чата без сервера. (это намек, что таких хостеров то и нет наверно).
> По протоколу Аськи не лучше?
У меня были исходники в свое время...
Тогда встречный вопрос. Аська общается с серверов, который написан на пхп(или пёрле). Допустим я каким-то образом прикручу свою прогу к их серверу и заставлю думать его(сервер) что "это" ISeekU к нему обращается. Но как потом мне заставить свой чат не отправлять и не принимать мессаги с айсикьюшных прог?
Или я не так понял. (кстати, спасибо за идею).
А есть ли еще какие-то варианты?
Или встречный вопрос - если на пхп писать, то как отправить сообщение в программу из скрипта? (хотя наверно я не в тот форум пишу). Вот, например, когда кто-то отправляет сообщение, то передается строка типа lkjhg.php?fff=uuu&hgf=pop&...... А скрипт потом посылает принятое всем остальным. Сответсвенно вопрос: как прогой на делфи это поймать(сообщение)?
← →
aa5E1 (2003-08-09 00:54) [9]вот как сделал это я:
unit uMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
WSocket, ComCtrls, ExtCtrls, StdCtrls, RVEdit, RVScroll, RichView,
RVStyle, trctrls, NMUDP, Buttons, ImgList, Menus, abcmenu;
type
TChatMessage = record
code: char;
param1: string;
param2: string;
param3: string;
param4: string;
end;
TfMain = class(TForm)
GroupBox1: TGroupBox;
Panel2: TPanel;
Panel3: TPanel;
PageControl1: TPageControl;
TabSheet1: TTabSheet;
sChat: TRVStyle;
rvChat: TRichView;
Splitter2: TSplitter;
GroupBox2: TGroupBox;
Splitter1: TSplitter;
Splitter3: TSplitter;
GroupBox3: TGroupBox;
teNick: TFlatEdit97;
lvNicks: TListView;
udp1: TNMUDP;
SpeedButton1: TSpeedButton;
ImageList1: TImageList;
mChat: TMemo;
mTopic: TMemo;
pmNicks: TabcPopupMenu;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
N4: TMenuItem;
N5: TMenuItem;
SpeedButton2: TSpeedButton;
procedure FormCreate(Sender: TObject);
procedure udp1DataReceived(Sender: TComponent; NumberBytes: Integer;
FromIP: String; Port: Integer);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure SpeedButton1Click(Sender: TObject);
procedure teNickKeyPress(Sender: TObject; var Key: Char);
procedure mChatKeyPress(Sender: TObject; var Key: Char);
procedure teNickExit(Sender: TObject);
procedure mTopicKeyPress(Sender: TObject; var Key: Char);
procedure N3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure SendIt(str:string);
function GetMessage(str: string):TChatmessage;
function GetParam(var tmp:string):string;
procedure ChatString(Chat:TChatMessage);
procedure ReportIn(Chat:TChatMessage);
procedure Report(Chat: TChatMessage);
end;
var
fMain: TfMain;
Nick: string[30];
implementation
{$R *.DFM}
procedure TfMain.FormCreate(Sender: TObject);
begin
Nick := teNick.Text;
SendIt("4"+Nick+#00+"#Main"+#00+"00");
end;
procedure TfMain.SendIt(str: string);
var
MyStream: TMemoryStream;
Begin
MyStream := TMemoryStream.Create;
try
MyStream.Write(Str[1], Length(Str));
UDP1.SendStream(MyStream);
finally
MyStream.Free;
end;
end;
procedure TfMain.udp1DataReceived(Sender: TComponent; NumberBytes: Integer;
FromIP: String; Port: Integer);
var
MyStream: TMemoryStream;
TmpStr: String;
ChatMessage: TChatMessage;
begin
MyStream := TMemoryStream.Create;
try
UDP1.ReadStream(MyStream);
SetLength(TmpStr,NumberBytes);
MyStream.Read(TmpStr[1],NumberBytes);
finally
MyStream.Free;
end;
ChatMessage := GetMessage(TmpStr);
case ChatMessage.code of
"0": Report(ChatMessage);
"1": ReportIn(ChatMessage);
"2": ChatString(ChatMessage);
end;
end;
function TfMain.GetMessage(str: string): TChatmessage;
begin
Result.code := str[1];
delete(str,1,1);
Result.param1 := GetParam(str);
Result.param2 := GetParam(str);
Result.param3 := GetParam(str);
Result.param4 := GetParam(str);
end;
function TfMain.GetParam(var tmp: string): string;
var
i: integer;
begin
Result := "";
for i:= 1 to length(tmp) do
if Tmp[i] = #00 then
break
else
Result := Result + tmp[i];
delete(Tmp,1,Length(Result)+1);
end;
procedure TfMain.ChatString(Chat: TChatMessage);
var
st: integer;
begin
st := 0;
if Chat.param2 = teNick.Text then
st := 1;
rvChat.AddNL("<"+chat.param2+"> "+chat.param3,st,0);
rvChat.FormatTail;
end;
procedure TfMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
SendIt("5"+Nick+#00+"#Main"+#00+"00");
end;
procedure TfMain.SpeedButton1Click(Sender: TObject);
begin
lvNicks.Items.Clear;
SendIt("0"+Nick+ #00 + "00");
end;
procedure TfMain.ReportIn(Chat: TChatMessage);
begin
//1Terran|zilot|10
if Chat.param1 = Nick then
lvNicks.Items.Add.Caption := Chat.param2;
end;
procedure TfMain.Report(Chat: TChatMessage);
var
mon: integer;
begin
//if fMain.Showing then
// mon := 1;
SendIt("1"+Chat.param1+#00+Nick+#00+#1);//+"03"+inttostr(mon));
end;
procedure TfMain.teNickKeyPress(Sender: TObject; var Key: Char);
begin
if key = #13 then
begin
SendIt("3"+Nick+#00+teNick.Text+#00+"10"+#00);
Nick := teNick.Text;
end;
end;
procedure TfMain.mChatKeyPress(Sender: TObject; var Key: Char);
begin
if key = #13 then
begin
SendIt("2#Main" + #00 + Nick + #00 + mChat.Lines.Strings[mChat.Lines.Count-1] + #00);
end;
end;
procedure TfMain.teNickExit(Sender: TObject);
begin
teNick.Text := Nick;
end;
procedure TfMain.mTopicKeyPress(Sender: TObject; var Key: Char);
begin
if key = #13 then
begin
SendIt("B"+mTopic.Lines.GetText);
( Sender: TObject)вот как сделал это я:
unit uMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
WSocket, ComCtrls, ExtCtrls, StdCtrls, RVEdit, RVScroll, RichView,
RVStyle, trctrls, NMUDP, Buttons, ImgList, Menus, abcmenu;
type
TChatMessage = record
code: char;
param1: string;
param2: string;
param3: string;
param4: string;
end;
TfMain = class(TForm)
GroupBox1: TGroupBox;
Panel2: TPanel;
Panel3: TPanel;
PageControl1: TPageControl;
TabSheet1: TTabSheet;
sChat: TRVStyle;
rvChat: TRichView;
Splitter2: TSplitter;
GroupBox2: TGroupBox;
Splitter1: TSplitter;
Splitter3: TSplitter;
GroupBox3: TGroupBox;
teNick: TFlatEdit97;
lvNicks: TListView;
udp1: TNMUDP;
SpeedButton1: TSpeedButton;
ImageList1: TImageList;
mChat: TMemo;
mTopic: TMemo;
pmNicks: TabcPopupMenu;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
N4: TMenuItem;
N5: TMenuItem;
SpeedButton2: TSpeedButton;
procedure FormCreate(Sender: TObject);
procedure udp1DataReceived(Sender: TComponent; NumberBytes: Integer;
FromIP: String; Port: Integer);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure SpeedButton1Click(Sender: TObject);
procedure teNickKeyPress(Sender: TObject; var Key: Char);
procedure mChatKeyPress(Sender: TObject; var Key: Char);
procedure teNickExit(Sender: TObject);
procedure mTopicKeyPress(Sender: TObject; var Key: Char);
procedure N3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure SendIt(str:string);
function GetMessage(str: string):TChatmessage;
function GetParam(var tmp:string):string;
procedure ChatString(Chat:TChatMessage);
procedure ReportIn(Chat:TChatMessage);
procedure Report(Chat: TChatMessage);
end;
var
fMain: TfMain;
Nick: string[30];
implementation
{$R *.DFM}
procedure TfMain.FormCreate(Sender: TObject);
begin
Nick := teNick.Text;
SendIt("4"+Nick+#00+"#Main"+#00+"00");
end;
procedure TfMain.SendIt(str: string);
var
MyStream: TMemoryStream;
Begin
MyStream := TMemoryStream.Create;
try
MyStream.Write(Str[1], Length(Str));
UDP1.SendStream(MyStream);
finally
MyStream.Free;
end;
end;
procedure TfMain.udp1DataReceived(Sender: TComponent; NumberBytes: Integer;
FromIP: String; Port: Integer);
var
MyStream: TMemoryStream;
TmpStr: String;
ChatMessage: TChatMessage;
begin
MyStream := TMemoryStream.Create;
try
UDP1.ReadStream(MyStream);
SetLength(TmpStr,NumberBytes);
MyStream.Read(TmpStr[1],NumberBytes);
finally
MyStream.Free;
end;
ChatMessage := GetMessage(TmpStr);
case ChatMessage.code of
"0": Report(ChatMessage);
"1": ReportIn(ChatMessage);
"2": ChatString(ChatMessage);
end;
end;
function TfMain.GetMessage(str: string): TChatmessage;
begin
Result.code := str[1];
delete(str,1,1);
Result.param1 := GetParam(str);
Result.param2 := GetParam(str);
Result.param3 := GetParam(str);
Result.param4 := GetParam(str);
end;
function TfMain.GetParam(var tmp: string): string;
var
i: integer;
begin
Result := "";
for i:= 1 to length(tmp) do
if Tmp[i] = #00 then
break
else
Result := Result + tmp[i];
delete(Tmp,1,Length(Result)+1);
end;
procedure TfMain.ChatString(Chat: TChatMessage);
var
st: integer;
begin
st := 0;
if Chat.param2 = teNick.Text then
st := 1;
rvChat.AddNL("<"+chat.param2+"> "+chat.param3,st,0);
rvChat.FormatTail;
end;
procedure TfMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
SendIt("5"+Nick+#00+"#Main"+#00+"00");
end;
procedure TfMain.SpeedButton1Click(Sender: TObject);
begin
lvNicks.Items.Clear;
SendIt("0"+Nick+ #00 + "00");
end;
procedure TfMain.ReportIn(Chat: TChatMessage);
begin
//1Terran|zilot|10
if Chat.param1 = Nick then
lvNicks.Items.Add.Caption := Chat.param2;
end;
procedure TfMain.Report(Chat: TChatMessage);
var
mon: integer;
begin
//if fMain.Showing then
// mon := 1;
SendIt("1"+Chat.param1+#00+Nick+#00+#1);//+"03"+inttostr(mon));
end;
procedure TfMain.teNickKeyPress(Sender: TObject; var Key: Char);
begin
if key = #13 then
begin
SendIt("3"+Nick+#00+teNick.Text+#00+"10"+#00);
Nick := teNick.Text;
end;
end;
procedure TfMain.mChatKeyPress(Sender: TObject; var Key: Char);
begin
if key = #13 then
begin
SendIt("2#Main" + #00 + Nick + #00 + mChat.Lines.Strings[mChat.Lines.Count-1] + #00);
end;
end;
procedure TfMain.teNickExit(Sender: TObject);
begin
teNick.Text := Nick;
end;
procedure TfMain.mTopicKeyPress(Sender: TObject; var Key: Char);
begin
if key = #13 then
begin
SendIt("B"+mTopic.Lines.GetText);
end;
end;
procedure TfMain.N3Click(Sender: TObject);
begin
mChat.Lines.Add(lvNicks.Selected.Caption);
end;
end.
но это еще не идеал... это пародия на QChat
← →
aa5E1 (2003-08-09 00:58) [10]савсем забыл... :)... извините вот еще приложение DFM файл где и есть все необходимые настройки UDP компоненты :
object fMain: TfMain
...
object udp1: TNMUDP
RemoteHost = "192.168.1.255"
RemotePort = 8167
LocalPort = 8167
ReportLevel = 1
OnDataReceived = udp1DataReceived
Left = 119
Top = 178
end
...
end
end
жаль но все не влезло... если тебе интересно то могу выслать мылом исходник полный...
← →
Doctor Deejay (2003-08-09 11:59) [11]Насчет ICQ. Немного порылся в сети. Вот, что нашел:
.............Пакеты Клиент - Сервер посылаются с использованием протокола UDP ICQ серверу.
Пакеты, посылаемые от клиента к серверу, зашифрованы до их посылки, в отличие от пакетов, посылаемых от сервера клиенту, которые не шифруются............
Всё-таки UDP, но вы мне говорили, что это только в пределах подсети с диапазоном x.x.x.0 - x.x.x.255.
← →
SkyN (2003-08-09 12:07) [12]Мы говорили о широковешательных пакетах, а они только в подсети, и не обязатьло диапозон будет x.x.x.0 - x.x.x.255. А так если 2 IP извесно, то можно общаться и по UDP
← →
Doctor Deejay (2003-08-09 12:10) [13]
> А так если 2 IP извесно, то можно общаться и по UDP
А если эти IP просто прописывать где-то в инете (на каком-то сайте). А потом рассылать мессаги по этому списку? С сервера делать пинг и следить за состоянием чатлан?
← →
Rouse_ (2003-08-09 12:28) [14]В данном варианте сервер должен собирать информацию от чатов и отправлять ее остальным. Заметьте серверов может быть несколько и они также должны взаимодействовать между собой. А за своевременное обновление информации должен отвечать клиент. Единственно, можно сделать таймлимит на сервере, если по истечении таймлимита от клиента не пришла ни один пакет информации - считать его R.I.P.
Естественно все адреса серверов изначально должны быть известны клиентам.
Желаю успехов
← →
Проходил мимо (2003-08-09 12:41) [15]Не обязательно делать сервер в интернете, можно его установить на локальном компе. Завести специально мыло которое будет доступно всем участникам чата а в клиент запихнуть какой-нибудь idSMTP и пусть сервер отсылает письмо со своим IP на известное мыло. Клиенты его получают и подключаются к серверу... Разве не красота?
← →
Rouse_ (2003-08-09 13:00) [16]> Проходил мимо (09.08.03 12:41
Ну это один из вариантов, в прошлом году он обсуждался
Его плюсы высокая надежность
Минусы - издержки с разбором писем
Желаю успехов
← →
Doctor Deejay (2003-08-09 21:30) [17]
> отсылает письмо со своим IP на известное мыло. Клиенты его
> получают и подключаются к серверу...
У меня нет возможности повеситься на выделенке.. Уж простите, но финансы поют романсы. Мне же за это никто не платит. Чистый энтузиазм :)
> В данном варианте сервер должен собирать информацию от чатов
>
Кстати, я так и не понял принцип.
А почему сам чат не может это сделать? Например, закачать список, потом пропинговать всех. Если кто-то дохлый, то написать напротив его IP - RIP. И делать такую проверку при подключении и раз в минуту. Как вам такое?
> и пусть сервер отсылает письмо со своим IP на известное
> мыло. Клиенты его получают и подключаются к серверу...
> Ну это один из вариантов, в прошлом году он обсуждался
Это намек, что я не первый такой? А моих предшественников что-то вышло?
← →
Проходил мимо (2003-08-09 23:15) [18]> Doctor Deejay
И что всю сеть пинговать? Список то откуда взять?
А выделенка не нужна. Зачем?
Для непонятливых:
Подключаешься к интернету, твой сервер узнает IP и отсылает его в письме на мыло которое известно всем любителям этого самодельного чата :) Клиент получает письмо узнает адрес сервера и подключается к нему. И никакая выделенка не нужна. Или чат должен быть постоянно доступен? Тогда другое дело...
← →
Doctor Deejay (2003-08-10 03:00) [19]
> Или чат должен быть постоянно доступен? Тогда другое дело...
Да и я о том же. Я хочу сделать icq, но по возможности без сервера. Если не выйдет - попробовать юзать сервер самого icq. Если и этот вариант не катит, тогда я возьму в руки книгу по пхп, кот. пылится у меня на столе... и тряхну стариной... заранее знаю, что это самый геморный вариант... :(
> И что всю сеть пинговать? Список то откуда взять?
Попытаюсь объяснить проще:
Есть три человека, кот. хотят пообщаться, но заходят в разное время(9-00, 10-00 и 10-30). Где-то в инете, на каком-то сайте(народ.ру подойдет, но лучше платный) зарезервировано место. Запустившись, чат первого чела дописывает в файл строчку со своим ip, предварительно его закачав. Затем пингует все ip, кот. там прописаны. Если ответ пришел от кого-то, то он добавляется в список юзеров в чате. Такая проверка делается раз в минуту(или реже). Затем заходит второй чел и его чат делает тоже самое.
Теперь самое интересное: предположим, что кто-то закрых чат по 3 кнопкам или его просто отключило от инета. Тогда кто-то начнет проверять(пинговать), но не получит ответа. Вполне вероятно, что и ip у того чатла точно такой же очень не скоро появится(динамический, типа). Тут есть вариант - чистить список с мертвыми раз в сутки первым, кто зайдет и ставить где-то пометку о том, что сегодня чистка производилась.
Отправка сообщений всем - только из живых(кот. вися в списке).
Пометка IP как дохлого - писать рядом с ним RIP, например.
Размеры файлов:
для 100 человек - 123.123.123.123(15 знаков * 100 = 1,5 кила)
для 1000 - 15 кил.
Больше общаться не будет!
Единственное, что меня беспокоит - это скорость закачки и скачки этих файлов.
ВОТ ТАКОЙ АЛГОРИТМ. ПИСАТЬ Я ПОКА НЕ НАЧАЛ. ХОЧУ УСЛЫШАТЬ ВСЕ ЕГО МИНУСЫ... (если они есть)
> твой сервер узнает IP и отсылает его в письме на мыло которое
> известно всем любителям этого самодельного чата :)
P.S. А мне казалось, что все чатысамодельные
:)
← →
Doctor Deejay (2003-08-12 14:05) [20]Почему такое затишье????
← →
Doctor Deejay (2003-08-13 01:04) [21]Так вы одобряете мой алгоритм?
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2003.10.09;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.01 c