Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 31.07.2008, 03:37   #1
radiantor
 
Регистрация: 31.07.2008
Сообщений: 7
По умолчанию сериализация и десериализация

Всем привет.
пишу сетевую длл с использованием сокетов и протокола UDP.
И мне необходимо передавать некую последовательность чисел строкой.
Например: integer,shortint,shortint,real...
Как можно преобразовать это в строку-сериализовать?
Пс:находил методы с помощью потока, но мне это не подходит.
Мне бы сразу в массив байт и его я передам.
Спасибо.
radiantor вне форума Ответить с цитированием
Старый 31.07.2008, 08:34   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
находил методы с помощью потока, но мне это не подходит.
Почему? Это же та же передача побайтно.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 31.07.2008, 12:22   #3
radiantor
 
Регистрация: 31.07.2008
Сообщений: 7
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Почему? Это же та же передача побайтно.
С потоками придется в структуре сервера хранить ещё и свой поток, да
и кода больше получается tstream.create потом его free.

Я тут копал исходники TWriter и TReader. Там же как-то сделано
Код:
procedure TReader.Read(var Buf; Count: Longint); assembler;
asm
        PUSH    ESI
        PUSH    EDI
        PUSH    EBX
        MOV     EDI,EDX
        MOV     EBX,ECX
        MOV     ESI,EAX
        JMP     @@6
@@1:    MOV     ECX,[ESI].TReader.FBufEnd
        SUB     ECX,[ESI].TReader.FBufPos
        JA      @@2
        MOV     EAX,ESI
        CALL    TReader.ReadBuffer
        MOV     ECX,[ESI].TReader.FBufEnd
@@2:    CMP     ECX,EBX
        JB      @@3
        MOV     ECX,EBX
@@3:    PUSH    ESI
        SUB     EBX,ECX
        MOV     EAX,[ESI].TReader.FBuffer
        ADD     EAX,[ESI].TReader.FBufPos
        ADD     [ESI].TReader.FBufPos,ECX
        MOV     ESI,EAX
        MOV     EDX,ECX
        SHR     ECX,2
        CLD
        REP     MOVSD
        MOV     ECX,EDX
        AND     ECX,3
        REP     MOVSB
        POP     ESI
@@6:    OR      EBX,EBX
        JNE     @@1
        POP     EBX
        POP     EDI
        POP     ESI
end;
Я в асемблере плохо соображаю и с указателмя у мя туго.
Помогите как нибудь сделать из этого фугкцию читающую из буфера(массива байт).
radiantor вне форума Ответить с цитированием
Старый 31.07.2008, 12:42   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
С потоками придется в структуре сервера хранить ещё и свой поток
Мы об одних и тех же потоках говорим?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 31.07.2008, 13:32   #5
radiantor
 
Регистрация: 31.07.2008
Сообщений: 7
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Мы об одних и тех же потоках говорим?
я TStream или TMemryStream имею ввиду под потоком.Т.е поток информации-байт

У меня ДЛЛ работает(уже почти) следующим образом.
Например
Код:
a:=CreateServer(8080,Any_IP);
b:=CreateServer(6667,'127.0.0.1');
//так же создаю клиентов на клиентской стороне. CreateClient

//А отсылку информации хочу сделать примерно так.
ServerWriteInteger(a, 1234567);//пока всё в буфер пишется
ServerWriteInteger(a, 8812342);
ServerWriteByte(a, 128);
ServerSend(a);//теперь отправилось

//А на принимающей стороне так же тока
var 
  i,j:integer;
  b:byte;
begin
  ClientReadBegin;//сдесь берем сообщение(строку) из сокета
  ClientReadInteger(cl1,i);//и начинаем десериализацию.
  ClientReadInteger(cl1,j);
  ClientReadByte(cl1,b);
  ClientReadEnd;
Может так яснее станет.
radiantor вне форума Ответить с цитированием
Старый 31.07.2008, 15:45   #6
radiantor
 
Регистрация: 31.07.2008
Сообщений: 7
По умолчанию

Хорошо. Решил я попробовать сделать с помощью TWrite и TMemoryStream

Код:
TClients(Clientslist.Items[1]).wr.Position:=0;
  TClients(Clientslist.Items[1]).memstream.Position:=0;
  TClients(Clientslist.Items[1]).wr.WriteListBegin;
  TClients(Clientslist.Items[1]).wr.WriteVariant(random(9999));
  TClients(Clientslist.Items[1]).wr.WriteListEnd;

  TClients(Clientslist.Items[1]).serveraddr.sin_family:=AF_INET;
  TClients(Clientslist.Items[1]).serveraddr.sin_port:=htons(8123);
  TClients(Clientslist.Items[1]).serveraddr.sin_addr.S_addr:=inet_addr('127.0.0.1');

  SendTO(TClients(Clientslist.Items[1]).clientsocket,
  @TClients(Clientslist.Items[1]).memstream,sizeof(TClients(Clientslist.Items[1]).memstream),
  0,TClients(Clientslist.Items[1]).serveraddr,
  sizeof(TClients(Clientslist.Items[1]).serveraddr));
Пакет уходит. Но на сервер приходит что-то не то.
Ткните меня носом. Где моя ошибка?
radiantor вне форума Ответить с цитированием
Старый 01.08.2008, 10:35   #7
radiantor
 
Регистрация: 31.07.2008
Сообщений: 7
По умолчанию

Всем спасибо. Решение нашел.
Использовал Move с смещающимся указателем
radiantor вне форума Ответить с цитированием
Старый 02.08.2008, 00:27   #8
radiantor
 
Регистрация: 31.07.2008
Сообщений: 7
По умолчанию

Теперь у меня проблема в другом. На клиентской стороне не приходят пакеты от сервера.
Хотя на сервер шлются отлично.
Знаю что серверный сокет биндят (bind) на нужный порт.
Вопрос нужно ли делать bind на клиентском сокете? Может поэтому пакет не приходит?
radiantor вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
сериализация Crucian Общие вопросы C/C++ 5 18.11.2007 16:37