Клиент на Си, сервер на паскале...

Тема в разделе "WASM.NETWORKS", создана пользователем ZeroMemory, 1 апр 2005.

  1. ZeroMemory

    ZeroMemory New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2005
    Сообщения:
    79
    Приветствую!

    В озмикла такая ситуация: необходимо написать UDP клиент на СИ, а сервер на делфи.. В общем надо передадать просто 1 структуру по сокетам. Но делфи что-то не так ловит полоченную датаграмму. Я написал клиент и сервер на си - все пашет отлично. Но к этому адскому делфи чтото не прокатывает :dntknw:

    Вот структура для передачи:
    Код (Text):
    1.  
    2. typedef struct _tag_bot_info{
    3.     BOOL    s_ready;
    4.     BOOL    lan_modem; // true - LAN, false - modem
    5.     BYTE    os_type;
    6.     WORD    s_port;
    7.     WORD    bot_version;
    8.     WORD    cpu_speed;
    9.     WORD    total_ram;
    10.     WORD    ie_version; // LOBYTE - major; HIBYTE - minor version
    11.     DWORD   uptime; // minutes since startup
    12. } bot_info;
    13.  
    14. на делфи так:
    15.  
    16. type
    17.   bot_info = record
    18. s_ready: boolean;
    19.     lan_modem:  boolean; // true - LAN, false - modem
    20.     os_type:    byte;
    21.     s_port: word;
    22.     bot_version:word;
    23.     cpu_speed:  word;
    24.     total_ram:  word;
    25.     ie_version: word; // LOBYTE - major; HIBYTE - minor version
    26.     uptime:     dword; // minutes since startup
    27.   end;
    28.  
    29. Вот таким макаром пытаюсь получить датаграмму из делфи:
    30.  
    31. ...
    32. var buff: bot_info;
    33. ...
    34. r := recvfrom(hServerSocket, buff, sizeof(buff), 0, sin, fromlen);
    35. ...
    36.  
    37. но приходит чепуха... в то время как на си:
    38.  
    39. recvfrom(s, (char*)&buff, sizeof(buff), 0, (SOCKADDR*)&rem, &len);
    40.  
    41. все отлично проходит!
    42.  




    Кто-нить тут шарит в этом "адском" делфе? Что я делаю не правильНо?



    Спасибо!
     
  2. OLS

    OLS New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2005
    Сообщения:
    322
    Адрес:
    Russia
    Может быть проблема в делфийском выравнивании полей по границам слов ?

    Попробуй директиву компиляции



    ...

    type

    bot_info=packed record

    ...



    Она отключит выравнивание



    P.S. И кстати boolean в Делфи - однобайтовый
     
  3. ZeroMemory

    ZeroMemory New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2005
    Сообщения:
    79
    Спасибо! Трабл был действительно в размерности типов BOOL и boolean!

    А директива packed кстати, наоборот портит все... она уменьшает размер делфийской струкруры на 3 байта!! Получается 17 байт вместо 20!

    OLS

    Ты кстати не знаешь аналога этой директивы для си ? Был бы очень благодарен, т.к. сжатие даже на 3 байта для меня довольно критично..



    --zm
     
  4. OLS

    OLS New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2005
    Сообщения:
    322
    Адрес:
    Russia
    Увы, я "делфиец"
     
  5. MoKC0DeR

    MoKC0DeR New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2003
    Сообщения:
    136
    Адрес:
    Russia
    ZeroMemory

    pragma pack(1)
     
  6. OLS

    OLS New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2005
    Сообщения:
    322
    Адрес:
    Russia
    Кстати, что ты сделал :

    взял в Делфи 4-байтный тип

    или в С 1-байтный ?



    (в первом случае тебе директива никак не поможет - сжимать нечего)
     
  7. ZeroMemory

    ZeroMemory New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2005
    Сообщения:
    79
    2 MoKC0DeR



    Повтори по отношению к моей структуре плиз. Не очень понял как применить это..



    2 OLS



    Я конечно же в СИ заменил BOOL на 1-обайтный BYTE ;)
     
  8. ZeroMemory

    ZeroMemory New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2005
    Сообщения:
    79
    --- dup -----
     
  9. ZeroMemory

    ZeroMemory New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2005
    Сообщения:
    79
    --- dup ----- sorry
     
  10. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    ZeroMemory



    Дружеский совет: в обменных форматах записей\структур следует

    1) избегать использования специфических типов переменных,

    2) самому контролировать выравнивание глазками-ручками.



    Например, в Delphi тип boolean является generic, implementation dependence типом. Это означает, что борманы оставляют за собой право в будущем использовать любое физическое представление для этого типа. И хотя на деле это лишь страшилка (как был он байтом много лет назад, так и остается по сей день), тем не менее в обменных форматах лучше использовать fundamental типы фиксированного размера ByteBool или лучше просто byte, т.к. в дельфях еще и представление true отличается от С и бэйсика (в паскале 1, а в С xF..Fh).

    А вот что реально изменилось за давнюю историю паскаля и дельфи, так это представления типов integer (c 2 байт на 4) и real (c нестандартных 6 байт на стандартный 8 байт double). Обжегшись в свое время на молоке, я с тех пор для обмена (длл, файлы и т.п.) использую только типы фиксированного размера (fundamental).



    В случае когда важен размер и компактность структуры данных лучше самому следить за выравниванием. В дельфях для этого первым делом отключаем выравнивание директивой packed. Можно также использовать директивы компилятора $A- $A+: перед объявлением структуры отключаем, затем включаем (аналогичные директивы должны быть и в Си). Затем сами обеспечиваем выравнивание выбирая соответствующий тип и порядок следования полей и добавляя reserved байты. По общему правилу все word'ы должны быть выравнены на 2, dword'ы на 4 и размер записи д.б. кратен 4. Теперь смотрим на твою запись: вначале идут 3 байта и сбивают выравнивание всех последующих word и dword - не хорошо получается, вот тебе заботливый компилятор 3 байта и вставил. Можешь их сам вставить - будет один резервный байт и один ворд - может пригодиться в будущем. А если тебе каждый байт дорог, то придется что-то упаковать. К примеру первые два була можно заменить на один байт Flags с флагами s_ready = 1 и lan_modem = 2. Иногда просто порядок полей нужно правильно выбирать, например word;dword;word это не правильно, а dword;word;word - OK. В твоем случае то же: можно и не отключать выравнивание, а переставить dword первым, а все байты в конец - тебе то не все ли равно в каком порядке они идут.
     
  11. MoKC0DeR

    MoKC0DeR New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2003
    Сообщения:
    136
    Адрес:
    Russia
    ZeroMemory

    вставь перед описание твоей структуры
     
  12. ZeroMemory

    ZeroMemory New Member

    Публикаций:
    0
    Регистрация:
    9 янв 2005
    Сообщения:
    79
    Спасибо всем. Сделал чтоб 17 байт структура была и в делфи и си..