Форум: "Сети";
Текущий архив: 2003.10.23;
Скачать: [xml.tar.bz2];
ВнизПомогите найти компоненты для TCP... :) Найти похожие ветки
← →
Terminus (2003-08-25 16:39) [0]Господа! Сможет ли кто-нибудь посоветовать хорошие компоненты/модули для реализации TCP клиента/сервера? Сие необходимо для создания мультиплеера в игрухе... :)
Только, плз, не предлагать 2 варианта:
1. Писать самому.
2. THxTcpIpcUdp. Хороший модуль, но то, что код, перенесенный из стандартного примера в игру, перестал работать (невозможно добиться пересылки record) окончательно вывело меня из себя. :) Жаль...
Еще буду благодарен, если кто объяснит принципиальное отличие сервера синхронного и асинхронного. Литературу в INet"е почитал, но практической разницы так и не понял. :)
Заранее благодарен.
← →
Reindeer Moss Eater (2003-08-25 16:46) [1]Хороший модуль, но то, что код, перенесенный из стандартного примера в игру, перестал работать
А если перенести не в игру?
← →
Dimka Maslov (2003-08-25 16:47) [2]Лучше писать самому при помощи WinSock. Особых сложностей нет.
Синхронный сервер обрабатывает запросы клиентов последовательно в одном потоке, что уменьшает скорость и увеличивает надёжность, поскольку нет проблем с доступом к ресурсам, разделяемым между потоками. Асинхронный сервер при получении запроса клиента создаёт новый поток, который этот запрос и обрабатывает при увеличении скорости работы (клиент не ждёт завершения обработки других запросов) возникает серьёзная проблема доступа к разделяемым ресурсам при плохом решении которой программа часто получает конфликты доступа, которые не могут отловлены.
← →
Terminus (2003-08-25 16:49) [3]Попробую, но ... смешно. Код простой, инициализация и можно отправлять... Самое смешное, что отдельные переменные перекидываются (хотя бы та же SendString), а вот с record... В общем, вопрос остается в силе. :)
← →
Polevi (2003-08-25 16:49) [4]>что уменьшает скорость
это кто тебе такое сказал
← →
Reindeer Moss Eater (2003-08-25 16:51) [5]Самое смешное, что отдельные переменные перекидываются (хотя бы та же SendString), а вот с record... В общем, вопрос остается в силе. :)
Тебе наверное попалась какая-то особо интеллектуальная библиотека, которая распознает что с помощью ее пытаются передать. Строки или записи. Она видимо байты внимательно разглядывает и находит 10 отличий.
← →
Terminus (2003-08-25 17:09) [6]Тем, кто юзает HxTcpIpcUdp (поскольку альтернатив пока никто не предложил :)
Мда... Короче, видоизменил стандартный пример для отправки record, в составе которого есть PChar. Клиент запись отправляет, сервер принимает и отображает строку. Все нормально.
Переношу код, разделяя клиента и сервера в отдельные программы. Переменные svrTCP и clntTCP объявляю как отдельные переменные, вне TForm1. Сообщение отсылает теперь сервер клиенту. В результате, после получение записи клиентом вместо строки бред. Т.е. не бред, конечно, не явно содержимое некой другой области памяти, в которой моей строки нет. :) Вот такие пироги... :[
← →
Terminus (2003-08-25 17:11) [7]To Dimka Maslov
Я так понимаю, синхронный сервер нужен тогда, когда мне важно, чтобы запросы обрабатывались в той последовательности, в какой были отправлены?
← →
Reindeer Moss Eater (2003-08-25 17:22) [8]Переношу код, ....
....
Вот такие пироги... :[
Ты не объясняй, что ты делаешь, ты код покажи.
← →
Terminus (2003-08-25 17:48) [9]
unit Common;
{$DEFINE CLIENT}
{DEFINE SERVER}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
HxTcpIpcUdp;
type
TForm1 = class(TForm)
procedure FormShow(Sender: TObject);
{$IFDEF SERVER}
procedure OnNewClient(iDescr: Integer);
{$ENDIF}
private
{ Private declarations }
public
{ Public declarations }
{$IFDEF CLIENT}
procedure HandleClientDataAvailable(ptr: pointer; iSize: integer);
{$ENDIF}
end;
THeroInfo = record
RecordType: Byte;
Name: PChar;
end;
TDecorateInfo = record
RecordType: Byte;
Empty: Integer;
Name: PChar;
end;
var
Form1: TForm1;
svrTCP: THxTcpServer;
clntTCP: THxTcpClient;
Hero: THeroInfo;
Decorate: TDecorateInfo;
PHero: ^THeroInfo;
PDecorate: ^TDecorateInfo;
implementation
{$R *.DFM}
{$IFDEF CLIENT}
procedure TForm1.HandleClientDataAvailable(ptr: pointer; iSize: integer);
var
s: string;
z,i,j: Integer;
oRecordType: Byte;
begin
Move(ptr^,oRecordType,1);
case oRecordType of
1: begin
Move(ptr^,Hero,isize);
ShowMessage(StrPas(Hero.Name));
end;
2: begin
Move(ptr^,Decorate,isize);
ShowMessage(StrPas(Decorate.Name));
end;
end;
end;
{$ENDIF}
procedure TForm1.FormShow(Sender: TObject);
begin
{$IFDEF SERVER}
svrTCP := THxTcpServer.Create;
svrTCP.Port := "2003";
svrTCP.OnNewClient := OnNewClient;
svrTCP.Listen;
{$ENDIF}
{$IFDEF CLIENT}
clntTcp := THxTcpClient.Create;
clntTcp.ServerAddress := "localhost";
clntTcp.Port := "2003";
clntTcp.OnDataAvailable := HandleClientDataAvailable;
clntTcp.Connect;
{$ENDIF}
end;
{$IFDEF SERVER}
procedure TForm1.OnNewClient(iDescr: Integer);
begin
PHero:=@Hero;
PDecorate:=@Decorate;
PHero.RecordType:=1;
PDecorate.RecordType:=2;
PHero.Name:=PChar("Герой");
PDecorate.Name:=PChar("Декоративный объект");
SvrTcp.SendData(PDecorate,SizeOf(Decorate),0);
end;
{$ENDIF}
end.
Вот полный код неработующего модуля. Соответственно, для клиента компилируется один код, для сервера другой, но это неважно...
Суть в том, чт клиент по певому байту должен определить тип записи (и в видоизмененном стандартном примере исправно это делает) и вывести имя объекта. Разумеется, код тестовый, так что обращать внимание только на суть проблемы. :)
← →
Reindeer Moss Eater (2003-08-25 18:26) [10]TDecorateInfo = record
RecordType: Byte;
Empty: Integer;
Name: PChar;
end;
SvrTcp.SendData(PDecorate,SizeOf(Decorate),0);
При выполнении этого кода, поле Name из TDecorateInfo никуда не посылается. Вместо этого посылается значение указателя, который на приемном конце лишен всяческого смысла ибо указывает в космос.
← →
Terminus (2003-08-25 18:37) [11]И? Выход то где в этом случае? :)
Характерно, что если и сервер и клиент размещаются в одном модуле (в пресловутом стандартном примере), этот же код работает. Я вижу две причины, обе из которых мне не нравятся. :)
1. Две копии программы, запущенные паралельно, используют одну и ту же область памяти (что невозможно)
2. Причина бага в другом.
Так все таки, как организовать пересылку record структур? Можно, конечно, перед пересылкой запихивать содержимое record в текий буфер, и кидать уже его, а на другом конце опять заносить в record, но это уже извращение... :(
← →
Dimka Maslov (2003-08-25 18:39) [12]>Polevi
Скорость работы клиента при множественном подключении клиентов к серверу меньше если сервер работает в синхронном режиме именно за счёт ожидания, особенно если запрос приводит к передаче больших массивов данных. При небольшом объёме отправляемых пакетов замедление работы клиента не столь существенно.
>Terminus
TDecoreateInfo = record
RecordType: Byte;
RecordSize: LongInt;
Empty: LongInt;
NameLen: LongInt;
Name: array[0..0] of Char;
end;
← →
Reindeer Moss Eater (2003-08-25 18:41) [13]Характерно, что если и сервер и клиент размещаются в одном модуле (в пресловутом стандартном примере), этот же код работает. Я вижу две причины, обе из которых мне не нравятся. :)
Указатель переданный клиенту, продолжает указывать на то место в памяти, куда он указывал до своего путешествия к клиенту.
Вот и все "характерно"
← →
Reindeer Moss Eater (2003-08-25 18:42) [14]Так все таки, как организовать пересылку record структур? Можно, конечно, перед пересылкой запихивать содержимое record в текий буфер, и кидать уже его, а на другом конце опять заносить в record, но это уже извращение... :(
Почему извращение? Потому что требует дополнительного программирования нескольких строк?
← →
Dimka Maslov (2003-08-25 18:45) [15]>Terminus
Зайди на http://icq2000cc.hobi.ru/ там подробно описано как организовать пересылку записей со строками переменной длины.
← →
Reindeer Moss Eater (2003-08-25 18:47) [16]Так все таки, как организовать пересылку record структур?
Не в самих Record"ах проблема, а в Record"ах, имеющих указатели.
← →
Terminus (2003-08-25 18:59) [17][i]To Dimka Maslov[/i]
Спасибо, посмотрю, буду пробовать...
[i]To Reindeer Moss Eater
Почему извращение? Потому что требует дополнительного программирования нескольких строк?[/i]
В общем, хотелось бы не утяжелять прогу всем этим, но, похоже, иного выхода нет. :) Ладно, спасибо всем за помощь, пойду эксперементировать...
← →
Reindeer Moss Eater (2003-08-25 19:36) [18]В общем, хотелось бы не утяжелять прогу всем этим
Надо очень сильно попотеть, что бы утяжелить свою прогу кодом (именно кодом).
← →
Terminus (2003-08-25 20:50) [19]Еще раз спасибо. :) Помещаю теперь в TByteArray и после доставки собираю обратно в record...
Еще. Предполагается, что пакеты, по большей части, будут небольшими (несколько десятков байт), но серверу прийдется рассылать все это десяткам клиентов (как минимум) и весьма часто... Поэтому и хотелось ускорить процедуры пересылки... Хотя может, зря все это, мелочи...
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2003.10.23;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.011 c