Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2010.11.21;
Скачать: [xml.tar.bz2];

Вниз

Передача типов через 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.005 c
15-1281028926
Правильный$Вася
2010-08-05 21:22
2010.11.21
заклинило виндовый обновлятор


2-1283178522
ZV
2010-08-30 18:28
2010.11.21
Преоброзование данных


2-1283260525
Stenfit
2010-08-31 17:15
2010.11.21
Сохранение списка


2-1282770205
Arhi2med
2010-08-26 01:03
2010.11.21
как последовательно читать текст если элементы разделены ;


15-1282002935
Дмитрий С
2010-08-17 03:55
2010.11.21
Синхронизация доступа к хешу.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский