-
отправить через TidTCPServer, забыл уточнить
-
> у меня не получается
Показывай что делал .. С подробными комментариями движений своей мысли для каждой строчки своего кода ..
-
> отправить через TidTCPServer, забыл уточнить
Хоть через луну !
Ход своей мысли продемонстрируй ..
-
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IdBaseComponent, IdComponent, IdCustomTCPServer, IdTCPServer, Buttons,
idContext;
type
TForm1 = class(TForm)
Server: TIdTCPServer;
procedure ServerConnect(AContext: TIdContext);
procedure ServerExecute(AContext: TIdContext);
private
public
end;
_Pack = Record
Primary_handle : Cardinal;
Secondary_handle : Cardinal;
Primary_index : string[8];
Secondary_index : string[8];
End;
Function Connect_to_Clients( Handle : cardinal; index : string):boolean;
Function GetHandleByHandle(Handle : cardinal):Cardinal;
Procedure Transfer(handle : cardinal; str: string);
var
Form1: TForm1;
Pack : _Pack;
Clients : Array of _Pack;
Clients_count : integer;
implementation
procedure TForm1.ServerConnect(AContext: TIdContext);
var
str : string;
begin
AContext.Connection.Socket.WriteLn('Welcame'+#13+'Index[8]: ');
Str:=AContext.Connection.Socket.ReadLn();
if length(str)<>8 then
begin
AContext.Connection.Socket.WriteLn('Error length index');
AContext.Connection.Disconnect;
end
else
begin
if Connect_to_clients(Acontext.Connection.Socket.Binding.Handle,str) then
begin
Acontext.Connection.Socket.WriteLn('Start transfer');
end
else
begin
Acontext.Connection.Socket.WriteLn('Error registration');
AContext.Connection.Disconnect;
end;
end;
end;
Function Connect_to_Clients( Handle : cardinal; index : string):boolean;
var
i : integer;
register_ : boolean;
begin
Result:=false;
for i:=0 to Clients_count-1 do
begin
if ((Clients[i].Primary_index=index)or(Clients[i].Secondary_index=index)) then
begin
if Clients[i].Primary_index=index then
begin
Clients[i].Secondary_handle:=Handle;
Clients[i].Secondary_index:=index;
result:=true;
exit;
end;
if Clients[i].Secondary_index=index then
begin
Clients[i].Primary_handle:=Handle;
Clients[i].Primary_index:=index;
result:=True;
exit;
end;
end;
end;
inc(clients_count);
SetLEngth(Clients,Clients_count);
Clients[Clients_count-1].Primary_handle:=handle;
Clients[Clients_count-1].Primary_index:=Index;
Result:=True;
end;
procedure TForm1.ServerExecute(AContext: TIdContext);
var
msg : string;
i : integer;
begin
msg:=AContext.Connection.Socket.ReadLn();
if msg='\handle\' then
begin
AContext.Connection.Socket.WriteLn(IntTOStr(AContext.Connection.Socket.Binding.H andle));
exit;
end;
if msg='\clients\' then
begin
for i:=0 to CLients_count-1 do
begin
AContext.Connection.Socket.WriteLn(
'-----------------'+#13+'Couple '+IntToStr(i+1)+#13+
'PH: '+IntToStr(Clients[i].Primary_handle)+#13+
'PI: '+Clients[i].Primary_index+#13+
'SH: '+IntToStr(Clients[i].Secondary_handle)+#13+
'SI: '+Clients[i].Secondary_index);
end;
AContext.Connection.Socket.WriteLn('Done. '+IntToStr(Clients_count)+' couples.');
exit;
end;
if msg='\couples\' then
begin
AContext.Connection.Socket.WriteLn(INtToStr(Clients_count)+' couples.');
exit;
end;
if msg='\GetHandleByHandle\' then
begin
AContext.Connection.Socket.WriteLn(IntToStr(GetHandleByHandle(AContext.Connectio n.Socket.Binding.Handle)));
end;
Transfer(AContext.Connection.Socket.Binding.Handle,msg);
end;
Procedure Transfer(handle : cardinal; str: string);
var
_handle : cardinal;
begin
_handle:=GetHandleByHandle(handle);
end;
Function GetHandleByHandle(Handle : cardinal):Cardinal;
var
i : integer;
begin
result:=0;
for i:=0 to Clients_count-1 do
begin
if Clients[i].Primary_handle=handle then
begin
result:=Clients[i].Secondary_handle;
exit;
end;
if Clients[i].Secondary_handle=handle then
begin
Result:=Clients[i].Primary_handle;
exit;
end;
end;
end;
end.
вот, вроде как бы всё работает, но до определенного затыка в процедуре Transfer.
-
Тихий ужас..
Хендлы какие-то куда-то отправляются ..
Ты в состоянии изложить формальное описание разработанного тобой протокола инф.обмена между клиентами и сервером ?
-
За каким тебе понадобились хендлы, если у тебя есть список уникальных объектов IdTCP.Server.Connections, каждый из которых отражает контекст соединения сервера с одним из его активных клиентов ?
-
да что есть? ничего там нет, просил же показать то о чем вы всё время говорите, так вы не можете. Зачем вам всё время нужен этот протокол я никак не понимаю, у меня проблема совсем в другом.
-
> если у тебя есть список уникальных объектов IdTCP.Server. > Connections
У вас может быть и есть, а у меня нету. есть только Server.Contexts в котором есть LockList в котором уже я ничего не нашел. Вот просил же хоть что-то показать конкретное, а вы мне только наводящие вопросы задаете, которые ни на что не наводят меня(
-
> Зачем вам всё время нужен этот протокол я никак не понимаю
Для того чтобы понять "язык", на котором ты пытаешься заствить разговаривать своих клиентов со своим сервером - что, кому, когда, в каком формате и при каких условиях передается/принимается
Пойми, наконец, что без формализованного прикладного протокола инф.обмена ничего путного у тебя не получится. Любую сколь-либо серьезную сетевую разработку следует начинать с листа бумаги и авторучки, а не со слепого тыканья в компонентах.
> у меня проблема совсем в другом
Не надо себе их, проблемы эти, создавать, тогда и не придется их потом героически преодолевать.
Взять хотя бы элементарное, о чем я у тебя уже спросил в [45] ..
-
> у меня нету. есть только Server.Contexts
Да ну какая разница ? пусть будет не Connections, а Contexts - суть свойства от этого не меняется.
> LockList в котором уже я ничего не нашел
Что и где ты искал из того что не нашел ?
-
> вопросы задаете, которые ни на что не наводят меня
Это печально. Очень.
-
> Zalm (07.09.2009 12:57:47) [47]
Так вопросы задаются, потому что от тебя не поступило полной информации, если не ты, то мы.
-
> Zalm
Ты вообще осознаешь, что работу с каждым из своих клиентов IdTCP-сервер осуществляет в отдельном дополнительном треде ? Судя по
> У TServerSocket было проще всё, ну или понятней
ты обязан это осознавать, ибо в режиме stThreadBlocking TServerSocket работает точно так же как и IdTCP-сервер. Если осознаешь, то почему не выполняешь обязательную синхронизацию доступа к потоконебезопасным ресурсам, таким как, например, массив Clients, переменную Clients_count ?
-
Ну нету никакого протокола. В коде же видна идея как осуществляется обмен. При подключении "зарегистрировали" клиента, и всё, потом другой клиент подключается, такая же процедура, если они вводят один и тот же индекс, они получаются в паре, и сервер сразу передает между ними абсолютно всё что шлют (текст). Клиенты к этому серверу-посреднику обратиться никак не могут, ибо незачем. > За каким тебе понадобились хендлы, если у тебя есть список > уникальных объектов IdTCP.Server.Connections, каждый из > которых отражает контекст соединения сервера с одним из > его активных клиентов ?
а как записывать какие-то данные о клиенте что бы потом знать кто с кем в паре? Записать хендл мне показалось более целесообразно так как я видел функцию BindingByHandle, я подумал что можно по обработчику пробиться до сокета который он обрабатывает. Но идея завалилась. А толку записать порт и адрес как вы говорили? что мне потом с ними делать? > > LockList в котором уже я ничего не нашелЧто и где ты искал > из того что не нашел ?
Ну вот Server.Contexts.LockList а дальше что? есть Items[index:integer]:pointer, это единственное что вызывает какое-то внимание, но сделать тоже ничего не получается с этим. Так что чем может помочь этот LockList я не понимаю, и вы подсказать не можете. видел кусок из примера для инди 9
List := tcpServer.Threads.LockList;
try
for Count := 0 to List.Count -1 do
try
TIdPeerThread(List.Items[Count]).Connection.WriteLn(Msg);
except
TIdPeerThread(List.Items[Count]).Stop;
end;
finally
tcpServer.Threads.UnlockList;
end;
Они себе в переменную типа TList копируют себе этот LockList и рассылают всем сообщение. ТОлько что такое TIdPeerThread я не знаю, у меня такого нет. У них есть еще IdThreadMgrDefault1: TIdThreadMgrDefault; это в описании, тоже не знаю что это, у меня ткого нет. Вобщем жаль что не хотите ничего конкретного подсказать.
-
> Ты вообще осознаешь, что работу с каждым из своих клиентов > IdTCP-сервер осуществляет в отдельном дополнительном треде > ?
это да, это я знаю. > почему не выполняешь обязательную синхронизацию доступа > к потоконебезопасным ресурсам, таким как, например, массив > Clients, переменную Clients_count ?
не знаю, я такого раньше не делал, проблем как мне казалось из-за этого не было. да и как это синхронизацию я не знаю, я с этим не сталкивался к сожалению
-
Ну нету никакого протокола.
У тебя ничего не получится.
-
> Ну нету никакого протокола
Ты прикидываешься или где ?
Как это "нету" ?
А это, к примеру, что по-твоему
> 'Welcame'
?
Почему именно "велцаме" у тебя фигурирует, а не "Здарофф, чувак ! Ет я, сервер, с тобой разговариваю" ?
-
> Ну вот Server.Contexts.LockList а дальше что?
Ну и что толку тебе объяснять про "дальше что", если межпоточная синхронизация и защита ресурсов для тебя что новые ворота ?
-
> что такое TIdPeerThread я не знаю, у меня такого нет
В 10-ке элементами этого списка явл-ся объекты класса TIdContext
-
про ресурсы ему еще рано. он кажется самого главного не понял: если хочется, чтобы сервер имел возможность отправки сообщения в произвольный момент времени, то клиент такого сервера должен постоянно висеть в процедуре чтения буфера и ни на что иное не отвлекаться. При этом он теряет возможность отправлять на сервер что-либо по своей инициативе. Причем на все время своей сессии.
|