-
Добрый день.
Подскажите пожалуйста как можно реализовать следующее:
Есть тип:
type
TClientsData = class(TObject)
UIN: Integer;
Password: String;
end;
var
Data: TClientsData;
begin
Data := TClientsData.Create;
Data.Login := 450355355;
Data.Password := '';
end;
Как отправить Data через TClientSocket, а на TServerSocket принять??
Зарание благодарен
-
TClientsData = record
UIN: Integer;
Password: shortstring;
end;
var cd : TClientsData;
.....
soket.WriteBuff(cd,SizeOf(TClientsData));
-
Спасибо, Медвежонок Пятачок :)
Не подскажешь еще одно.
Вот на серверной стороне программы делаю так
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 Пустой
-
Data := TClientsData.Create;
А должен быть тот же тип что и при отправке.
-
> А должен быть тот же тип что и при отправке.
Точно. Спасибо огромное :)
-
> Calligraff
Все равно работать не будет
-
ВСе. заработало!
только теперь другая проблема
Есть тип:
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.
Как исправить и как быть со строками большой длины?
Зарание благодарен.
-
> как быть со строками большой длины?
их нужно отправлять принимать отдельно, а не в составе структуры
-
Может как-то переводить переменную в Pointer и посылать? Но тогда я тем более не имею представления как
-
см. SendText, ReceiveText
-
SendText, ReceiveText - не вариант, так как с текстом необходимо передавать данные
FUIN: Integer;
TUIN: Integer;
TypeData: Shortint;
-
> Calligraff © (10.12.08 15:09) [10]
Раз ты озаботился передачей-приемом дин.типов данных с управляемым временем жизни, таких как AnsiString, затею с передачей структуры "одним махом" выбрось из головы.
Для для передачи/приема данных типа AnsiString используй Send/ReceiveText
Для для передачи/приема иных данных используй SendStream, Send/ReseiveBuf.
-
Ясно.
Прям неудобно, но у меня еще возник вопрос
Как задать подключению определенный ID, например такой же как и UIN пользователя для того чтобы можно было быстро отправлят сообщение от одного пользователя к тому, которому адресованно сообщение не ища в искусственно созданой таблице активных пользователей адресата.
-
Или может есть другие варианты?
-
"не ища" не получится.
> в искусственно созданой таблице
Не надо создавать никакие "искуственные таблицы".
Список активных клиентов сервера доступен в ServerSocket.Socket.Connections.
У каждого эл-та списка - объекта TServerClientWinSocket - есть св-во Data, которое предназначено для хранения любой индивидуальной клиентской инф-ции.
-
Угумс...
Тогда как в Socket.Data (кот. имеет тип Pointer) запихнуть целое (типа Integer) число???
-
> как в Socket.Data (кот. имеет тип Pointer) запихнуть целое
szieof(pointer) >= sizeof(integer)
-
Не понял немного.. поподробнее можно.. Дело в том, что с типом Pointer не работал
Зарание благодарен
-
Понял как!
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;
-
можно и без класса-обертки
pointer = integer в 32 битных ОС и int64 в 64-битных
-
ясно
-
Спасибо огромное :)
-
> Для для передачи/приема данных типа AnsiString используй
> Send/ReceiveText
Тогда как указать, что данный текст посылается определенному пользователю в сети??
-
> как указать, что данный текст посылается определенному пользователю
> в сети?
Перед посылкой текста посылай инф-цию о том кому он адресован.
-
День добрый
возникли еще вопросики :)
буду рад помощи.
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 данные есть.
Подскажите как быть?
-
В коде куча грубейших ошибок, демонстрирующих полное непонимание тобой предмета.
Data.DataPointer := Contacts; // здесь ты скопировал указатель на объект
Contacts.Free; // и тут же уничтожил этот объект, теперь скопированная ссылка смотрит в никуда (в поле Data.DataPointer отныне "мусор")
..
Contacts := TList.Create; // здесь ты создан новый объект и записал ссылку на него в перем-ю Contacts
Contacts := Data.DataPointer; // а здесь ты похерил эту ссылку, затерев ее "мусором" из Data.DataPointer, появившемся там при см.выше обстоятельствах
Ну и твоя работа с объектом Query в части хотя бы навигации по нему не выдерживает никакой критики.
-
Согласен в запросах исправлюсь. Тип Pointer - поучу :)
Тогда другой вопрос.
вот когда я передаю
formMain.ClientSocket1.Socket.SendBuf(Data,SizeOf(RClientLoginInfo));
то Data - Это у меня какой-то тип определенный, в данном случае Data: RClientLoginInfo; и на клиенте я получаю данные и все в порядке.
НО, допустим я хочу в передавать разные типы в зависимости от запросов клиента
наример есть два типа:
Data: RClientLoginInfo;
Data: RClientContactList;
Каким образом можно узнать на клиентской машине, какой именно тип я передал?
Зарание благодарен.
-
> Каким образом можно узнать на клиентской машине, какой именно
> тип я передал?
Ну ты же сам сказал - в зависимости от запросов клиента.
Если клиент запросил конкретно RClientLoginInfo, то совершенно очевидно, что ожидает он ответ сервера в формате именно RClientLoginInfo и ни в каком ином.
-
согласен, но иногда сервер должен будет передавать данные без запроса например обновление информации у клинтов о текущем состоянии.
тогда получится клиент-программа не будет знать что за тип ей пришел
Как можно поступить здесь?
-
тогда получится клиент-программа не будет знать что за тип ей пришел
для этого люди придумали понятие "протокол"
-
Ввведи в спецификацию своего прикл.протокола префикс типа инф.пакета.
Любой передаваемый (неважно от кого кому) пакет предваряется передачей соотв.префикса.
Для не болоее чем 256-ти различных типов пакетов достаточно префикса размеров в 1 байт.
-
Сергей, к сожаления я не силен в протоколах.
Я использую компоненты TServerSocket и TCkientSoket
Подскажи пожалуйста, где мне копать, чтобы разобраться с префиксом?
-
> не силен в протоколах
Речь идет о твоем собственном прикладном протоколе информационного обмена !
А компоненты TServerSocket и TCkientSoket предназначены лишь для осуществления соединения и передачи данных любого содержания между клиентами и сервером.
Префикс - это тоже данные.
-
Где можно почитать о прикладных протоколах и как их писать?
-
Возьми за пример для изучения любой из известных протоколов - ftp, http, smtp, pop3
В Тырнете подробных описаний этих протоколов (кто, кому, что, в каком формате, в какой последовательности и при каких условиях передает) - как грязи..
-
ЗАРАААБООООТАЛОООО!!! :)
-
Сергей, а не подскажешь, как в функции, например
function MyQuery(inSQL: String): Boolean;
begin
..........
end;
выполнить запрос к SQL так, чтобы он не зависил от компонента TQuery находящегося на форме.
Т.е. выполнить запрос без компонента
-
function MyQuery(inSQL: String): Boolean;
begin
Result := True;
end;
-
function MyQuery(inSQL: String): Boolean;
var
Query: TQuery;
begin
Query := TQuery.Create(nil);
try
.....
finally
Query.Free;
end;
end;
-
не не не, это с компонентом
:)
-
> это с компонентом
Но не на форме же)
-
А не подскажешь, как массив TMSGARRAY = array[0..7168] of byte; записать в поле таблицы и каким типом должно быть поле?
БД MSSQL2000
-
Вопросы по работе с СУБД задавай в соотв.конференции.
-
понял. спасибо