Конференция "Сети" » Передача memoryStream через UDP сокет. [D7]
 
  • xss22 (24.10.11 08:28) [0]
    Передача memoryStream через UDP сокет.
    Сейчас я передаю TPacket, так, как указано в примере ниже.

    Мне нужно преобразовать TPacket как memoryStream, передать его, затем сервер должен получить memoryStream и преобразовать его в TPacket.
    Помогите пожалуйста, как это можно сделать.

    Для чего мне это нужно? Мне нужно сжимать пакеты. Сам пакет я могу сжать, если он будет как memoryStream.

    Помогите пожалуйста с примером. Но скажу сразу, нужна реконструкция только моего примера. Примеры с INDY или ClientSocket прошу не предлогать.  Заранее спасибо!

    В данный момент у меня реализован клиент\сервер следующим образом:
    Сервер:

    TPacket = packed record
     Nick :string[15];
     PosX: Single;    //положение игрока на X оси координат
     PosY: Single;    //положение игрока на Y оси координат
     PosZ: Single;    //положение игрока на Z оси координат
     IdMap : string[4]; //ID карты, на которой находится игрок
     Addr      : TSockAddrIn; //адрес игрока
    end;



    procedure RecvProc(Param: Pointer); stdcall;
    var
     Count   : LongInt;
     From    : TSockAddrIn;
     FromLen : LongInt;
     Packet  : TPacket;
     i,j,k    : LongInt;
     t:boolean;
     nick:string;
     idarray:integer; //применяется только для ntConnect
     idRoom:integer; //номер комнаты.
     LP:integer;
    begin

    while true do begin
    FromLen := SizeOf(From);
    Count := recvfrom(ServerSocket, Packet, SizeOf(Packet), 0, From, FromLen);  //получение данных, присланных сокету
    if Count > 0 then begin






    Клиент:

    TPacket = packed record
     Nick :string[15];
     PosX: Single;    //положение игрока на X оси координат
     PosY: Single;    //положение игрока на Y оси координат
     PosZ: Single;    //положение игрока на Z оси координат
     IdMap : string[4]; //ID карты, на которой находится игрок
     Addr      : TSockAddrIn; //адрес игрока
    end;



    procedure Send(var Packet: TPacket; var Addr: TSockAddrIn);
    begin
     if sendto(SocketClient, Packet, SizeOf(Packet), 0, Addr, SizeOf(Addr)) <> SizeOf(Packet) then
     log('error: sendto'#13#10 + GetErrorString);
    end;

  • Сергей М. © (24.10.11 09:41) [1]
    > Мне нужно сжимать пакеты

    Чего там сжимать-то ?
    Пакет у тебя всего ничего - меньше полста байт размером, в сжатом виде размер пакета будет сопоставим с размером несжатого, если не больше ..

    type
     TMySuperPuperMemoryStream = class(TCustomMemoryStream)
     end;

    ..
    var
     MySuperPuperPacket: TPacket;
     MySuperPuperMemoryStream: TMySuperPuperMemoryStream;
    ..
     MySuperPuperMemoryStream := TMySuperPuperMemoryStream.Create;
     MySuperPuperMemoryStream.SetPointer(@MySuperPuperPacket, SizeOf(MySuperPuperPacket));

  • xss22 (24.10.11 09:46) [2]
    Ну это только начало. А вообще структура будет данных TPacket будет большой.
    Где то 1500-2000 байт

    А на стороне сервера как сделать обратную операцию?
  • xss22 (24.10.11 09:56) [3]
    Я правильно делаю?:


    procedure Send(var Packet: TPacket; var Addr: TSockAddrIn);
    Var
      MySuperPuperMemoryStream: TMySuperPuperMemoryStream;
    begin
    MySuperPuperMemoryStream := TMySuperPuperMemoryStream.Create;
    MySuperPuperMemoryStream.SetPointer(@Packet, SizeOf(Packet));

    if sendto(SocketClient, MySuperPuperMemoryStream,  sizeof(MySuperPuperMemoryStream), 0, Addr, SizeOf(Addr)) <> sizeof(MySuperPuperMemoryStream) then
     log('error: sendto'#13#10 + GetErrorString);

    end;

  • Сергей М. © (24.10.11 10:06) [4]

    > Я правильно делаю?


    Нет конечно)

    MySuperPuperMemoryStream := TMySuperPuperMemoryStream.Create;
    try
     MySuperPuperMemoryStream.SetPointer(@Packet, SizeOf(Packet));
    // здесь сжимай свой стрим
    if sendto(SocketClient, MySuperPuperMemoryStream.Memory^,  MySuperPuperMemoryStream.Size, ...) then ..
    finally
     MySuperPuperMemoryStream.Free;
    end;

  • xss22 (24.10.11 10:08) [5]
    Сергей М., спасибо!
    А как на стороне сервера MySuperPuperMemoryStream преобразовать в TPacket ?
  • Сергей М. © (24.10.11 10:18) [6]
    создай мемстрим, в цикле ф-цией recv() читай из сокета и пиши в стрим методом WriteBuffer
  • xss22 (24.10.11 10:30) [7]
    Не работает.
    Наверное я опять что то не так делаю

    ..
    Var
      mem:TMemoryStream32;
      buffer:byte;
      len:integer;
    begin
    ..
    while true do begin
    mem:=TMemoryStream32.Create;
    Count := recvfrom(ServerSocket, buffer, len, 0, From, FromLen);
    mem.WriteBuffer(buffer, len);
    ..

  • xss22 (24.10.11 11:15) [8]
    Сергей М., плиз, помогите с серверной частью
  • xss22 © (24.10.11 13:17) [9]
    Так и не получается с серверной частью

    ..
    Var
     mem:TMemoryStream32;
     buffer:byte;
     len:integer;
    begin
    ..
    mem:=TMemoryStream32.Create;
    while true do begin
    Count := recvfrom(ServerSocket, buffer, len, 0, From, FromLen);
    mem.WriteBuffer(buffer, len);
    ..



    что я делаю не так?
  • Сергей М. © (24.10.11 21:02) [10]
    абсолютно всё.
    при таких печальных знаниях элементарных вещей фраза
    >INDY или ClientSocket прошу не предлогать
    выглядит ничем не объяснимой блажью.
 
Конференция "Сети" » Передача memoryStream через UDP сокет. [D7]
Есть новые Нет новых   [134436   +21][b:0][p:0.002]