Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.11.21;
Скачать: CL | DM;

Вниз

Передача типов через TClientsData   Найти похожие ветки 

 
Calligraff ©   (2008-12-10 10:53) [0]

Добрый день.

Подскажите пожалуйста как можно реализовать следующее:

Есть тип:

type
 TClientsData = class(TObject)
   UIN: Integer;
   Password: String;
 end;

var
  Data: TClientsData;
begin
Data := TClientsData.Create;
Data.Login := 450355355;
Data.Password := "";

// TClientSocket
// Как отправить?

end;

Как отправить Data через TClientSocket, а на TServerSocket принять??

Зарание благодарен


 
Медвежонок Пятачок ©   (2008-12-10 11:46) [1]

TClientsData = record
  UIN: Integer;
  Password: shortstring;
end;

var cd : TClientsData;

.....

soket.WriteBuff(cd,SizeOf(TClientsData));


 
Calligraff ©   (2008-12-10 12:21) [2]

Спасибо, Медвежонок Пятачок :)

Не подскажешь еще одно.

Вот на серверной стороне программы делаю так


procedure TformMain.socketServerClientWrite(Sender: TObject;
 Socket: TCustomWinSocket);
var
  Data: TClientsData;
begin
ClientSocket1.Active := True;
Data := TClientsData.Create;
Socket.ReceiveBuf(Data,Socket.ReceiveLength);
end;


но в итоге Data.UIN = 0, а Data.Password Пустой


 
Медвежонок Пятачок ©   (2008-12-10 12:33) [3]

Data := TClientsData.Create;

А должен быть тот же тип что и при отправке.


 
Calligraff ©   (2008-12-10 12:39) [4]


> А должен быть тот же тип что и при отправке.

Точно. Спасибо  огромное :)


 
Сергей М. ©   (2008-12-10 13:04) [5]


> Calligraff


Все равно работать не будет


 
Calligraff ©   (2008-12-10 14:03) [6]

ВСе. заработало!

только теперь другая проблема

Есть тип:

type
 RClientLoginInfo = record
   FUIN: Integer;
   TUIN: Integer;
   TypeData: Shortint;
   Data: String[254];
 end;


Все отлично работает, НО. необходимо передать строку длиной более 255 символов. поэтому заменяю Data: String[254]; на Data: String;

В следствии чего при посылке данных от клиента к серверу
procedure SendRegInfo();
var
  Data: RClientLoginInfo;
begin
Data.FUIN := 1111111;
Data.TUIN := 2222222;
Data.TypeData := 0;
Data.Data := "<текст длиной более 255 символов>";

formMain.ClientSocket1.Socket.SendBuf(Data,SizeOf(RClientLoginInfo));
end;


и получение сервером данных

procedure TformMain.socketServerClientRead(Sender: TObject;
 Socket: TCustomWinSocket);
var
  Data: RClientLoginInfo;
begin
Socket.ReceiveBuf(Data,Socket.ReceiveLength);
Memo1.Lines.Add(Data.Data);
end;


на моменте строки Memo1.Lines.Add(Data.Data); возникает ошибка Out of Memory.

Как исправить и как быть со строками большой длины?

Зарание благодарен.


 
Сергей М. ©   (2008-12-10 14:17) [7]


> как быть со строками большой длины?


их нужно отправлять принимать отдельно, а не в составе структуры


 
Calligraff ©   (2008-12-10 14:21) [8]

Может как-то переводить переменную в Pointer и посылать? Но тогда я тем более не имею представления как


 
Сергей М. ©   (2008-12-10 14:37) [9]

см. SendText, ReceiveText


 
Calligraff ©   (2008-12-10 15:09) [10]

SendText, ReceiveText - не вариант, так как с текстом необходимо передавать данные
  FUIN: Integer;
  TUIN: Integer;
  TypeData: Shortint;


 
Сергей М. ©   (2008-12-10 16:00) [11]


> Calligraff ©   (10.12.08 15:09) [10]


Раз ты озаботился передачей-приемом дин.типов данных с управляемым временем жизни, таких как AnsiString, затею с передачей структуры "одним махом" выбрось из головы.

Для для передачи/приема данных типа AnsiString используй Send/ReceiveText
Для для передачи/приема иных данных используй SendStream, Send/ReseiveBuf.


 
Calligraff ©   (2008-12-10 16:08) [12]

Ясно.

Прям неудобно, но у меня еще возник вопрос

Как задать подключению определенный ID, например такой же как и UIN пользователя для того чтобы можно было быстро отправлят сообщение от одного пользователя к тому, которому адресованно сообщение не ища в искусственно созданой таблице активных пользователей адресата.


 
Calligraff ©   (2008-12-10 16:08) [13]

Или может есть другие варианты?


 
Сергей М. ©   (2008-12-10 16:20) [14]

"не ища" не получится.


> в искусственно созданой таблице


Не надо создавать никакие "искуственные таблицы".

Список активных клиентов сервера доступен в ServerSocket.Socket.Connections.
У каждого эл-та списка - объекта TServerClientWinSocket - есть св-во Data, которое предназначено для хранения любой индивидуальной клиентской инф-ции.


 
Calligraff ©   (2008-12-10 17:39) [15]

Угумс...

Тогда как в Socket.Data (кот. имеет тип Pointer) запихнуть целое (типа Integer) число???


 
clickmaker ©   (2008-12-10 17:52) [16]

> как в Socket.Data (кот. имеет тип Pointer) запихнуть целое

szieof(pointer) >= sizeof(integer)


 
Calligraff ©   (2008-12-10 17:53) [17]

Не понял немного.. поподробнее можно.. Дело в том, что с типом Pointer не работал

Зарание благодарен


 
Calligraff ©   (2008-12-10 18:01) [18]

Понял как!

type
 TUIN = class(TObject)
   UIN: Integer;
 end;

........

procedure TformMain.socketServerClientRead(Sender: TObject;
 Socket: TCustomWinSocket);
var
  Clnt: TUIN;
  Clnt1: TUIN;
begin
Clnt := TUIN.Create;
Clnt.UIN := 250355355;
Socket.Data := Clnt;
Clnt1 := TUIN.Create;
Clnt1 := Socket.Data;
Memo1.Lines.Add(IntToStr(Clnt1.UIN));
end;



 
clickmaker ©   (2008-12-10 18:14) [19]

можно и без класса-обертки
pointer = integer в 32 битных ОС и int64 в 64-битных


 
Calligraff ©   (2008-12-10 18:29) [20]

ясно


 
Calligraff ©   (2008-12-10 18:48) [21]

Спасибо огромное :)


 
Calligraff ©   (2008-12-10 18:56) [22]


> Для для передачи/приема данных типа AnsiString используй
> Send/ReceiveText


Тогда как указать, что данный текст посылается определенному пользователю в сети??


 
Сергей М. ©   (2008-12-10 19:48) [23]


> как указать, что данный текст посылается определенному пользователю
> в сети?


Перед посылкой текста посылай инф-цию о том кому он адресован.


 
Calligraff ©   (2008-12-11 15:03) [24]

День добрый

возникли еще вопросики :)

буду рад помощи.


procedure SendContactsList(Socket: TCustomWinSocket; Data: RUsrReceiveData);
var
  i: Integer;
  ToSocketID: Integer;
  Contact: TContactListID;
  Contacts: TList;
begin

 ....................

      Contacts := TList.Create;
      Contact := TContactListID.Create;
      for i := 1 to formMain.queryContactsList.RecordCount do begin
         formMain.queryContactsList.First;
         Contact.UIN := formMain.queryContactsList.FieldValues["uininlst_id"];
         Contact.Visiblity := formMain.queryContactsList.FieldValues["visiblity"];
         Contacts.Add(Contact);
         formMain.queryContactsList.Next;
      end;
      Contact.Free;
   end;
   formMain.queryContactsList.Close;
   Data.DataPointer := Contacts;
   Contacts.Free;

   // временная проверка
   Contacts := TList.Create;
   Contacts := Data.DataPointer;
   Contacts.Free;


Хотел проверить возможно ли обратно получить данные, но на строке Contacts := Data.DataPointer; ничего в Contacts от Data.DataPointer не присваивается, хотя в Data.DataPointer данные есть.

Подскажите как быть?


 
Сергей М. ©   (2008-12-11 16:06) [25]

В коде куча грубейших ошибок, демонстрирующих полное непонимание тобой предмета.

Data.DataPointer := Contacts; // здесь ты скопировал указатель на объект
Contacts.Free; // и тут же уничтожил этот объект, теперь скопированная ссылка смотрит в никуда (в поле Data.DataPointer отныне "мусор")

..

Contacts := TList.Create; // здесь ты создан новый объект и записал ссылку на него в перем-ю Contacts
Contacts := Data.DataPointer; // а здесь ты похерил эту ссылку, затерев ее "мусором" из Data.DataPointer, появившемся там при см.выше обстоятельствах

Ну и твоя работа с объектом Query в части хотя бы навигации по нему не выдерживает никакой критики.


 
Calligraff ©   (2008-12-12 10:52) [26]

Согласен в запросах исправлюсь. Тип Pointer - поучу :)

Тогда другой вопрос.

вот когда я передаю

formMain.ClientSocket1.Socket.SendBuf(Data,SizeOf(RClientLoginInfo));


то Data - Это у меня какой-то тип определенный, в данном случае Data: RClientLoginInfo; и на клиенте я получаю данные и все в порядке.

НО, допустим я хочу в передавать разные типы в зависимости от запросов клиента

наример есть два типа:
Data: RClientLoginInfo;
Data: RClientContactList;

Каким образом можно узнать на клиентской машине, какой именно тип я передал?

Зарание благодарен.


 
Сергей М. ©   (2008-12-12 10:59) [27]


> Каким образом можно узнать на клиентской машине, какой именно
> тип я передал?


Ну ты же сам сказал - в зависимости от запросов клиента.

Если клиент запросил конкретно RClientLoginInfo, то совершенно очевидно, что ожидает он ответ сервера в формате именно RClientLoginInfo и ни в каком ином.


 
Calligraff ©   (2008-12-12 11:02) [28]

согласен, но иногда сервер должен будет передавать данные без запроса например обновление информации у клинтов о текущем состоянии.

тогда получится клиент-программа не будет знать что за тип ей пришел

Как можно поступить здесь?


 
Медвежонок Пятачок ©   (2008-12-12 11:23) [29]

тогда получится клиент-программа не будет знать что за тип ей пришел

для этого люди придумали понятие "протокол"


 
Сергей М. ©   (2008-12-12 11:26) [30]

Ввведи в спецификацию своего прикл.протокола префикс типа инф.пакета.
Любой передаваемый (неважно от кого кому) пакет предваряется передачей соотв.префикса.

Для не болоее чем 256-ти различных типов пакетов достаточно префикса размеров в 1 байт.


 
Calligraff ©   (2008-12-12 12:01) [31]

Сергей, к сожаления я не силен в протоколах.

Я использую компоненты TServerSocket и TCkientSoket

Подскажи пожалуйста, где мне копать, чтобы разобраться с префиксом?


 
Сергей М. ©   (2008-12-12 12:08) [32]


> не силен в протоколах


Речь идет о твоем собственном прикладном протоколе информационного обмена !

А компоненты TServerSocket и TCkientSoket предназначены лишь для осуществления соединения и передачи данных любого содержания между клиентами и сервером.

Префикс - это тоже данные.


 
Calligraff ©   (2008-12-12 12:41) [33]

Где можно почитать о прикладных протоколах и как их писать?


 
Сергей М. ©   (2008-12-12 13:05) [34]

Возьми за пример для изучения любой из известных протоколов - ftp, http, smtp, pop3

В Тырнете подробных описаний этих протоколов (кто, кому, что, в каком формате, в какой последовательности и при каких условиях передает) - как грязи..


 
Calligraff ©   (2008-12-16 10:04) [35]

ЗАРАААБООООТАЛОООО!!! :)


 
Calligraff ©   (2008-12-16 10:07) [36]

Сергей, а не подскажешь, как в функции, например


function MyQuery(inSQL: String): Boolean;
begin
..........
end;


выполнить запрос к SQL так, чтобы он не зависил от компонента TQuery находящегося на форме.
Т.е. выполнить запрос без компонента


 
Медвежонок Пятачок ©   (2008-12-16 10:09) [37]

function MyQuery(inSQL: String): Boolean;
begin
Result := True;
end;


 
Сергей М. ©   (2008-12-16 10:11) [38]

function MyQuery(inSQL: String): Boolean;
var
 Query: TQuery;
begin
 Query := TQuery.Create(nil);
 try
.....
 finally
   Query.Free;
 end;
end;


 
Медвежонок Пятачок ©   (2008-12-16 10:19) [39]

не не не, это с компонентом
:)


 
Сергей М. ©   (2008-12-16 10:22) [40]


> это с компонентом


Но не на форме же)



Страницы: 1 2 вся ветка

Текущий архив: 2010.11.21;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.01 c
2-1283367516
Andrey K
2010-09-01 22:58
2010.11.21
В TListBox с помощью мыши поменять Items


15-1281190075
Кэти
2010-08-07 18:07
2010.11.21
Как отключить редирект


10-1170677069
Juice
2007-02-05 15:04
2010.11.21
Где находится библиотека типов для Excel 2003 ?


15-1281529846
И. Павел
2010-08-11 16:30
2010.11.21
Композиции типа Битлз


6-1199895934
Danger
2008-01-09 19:25
2010.11.21
Разобрать Chunked encoded