Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Отправка структуры TidUDP 
:(
    Опции темы
Sharkfire
Дата 24.4.2009, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 236
Регистрация: 30.11.2006
Где: Одесса

Репутация: 2
Всего: 2



Добрый день!
Как правильно отправить структуру через 

TidUDPClient->SendBuffer

у меня не получается пере конвертировать её в TByteDynArray !

как её потом корректно принять? (пере конвертировать обратно)...


PM MAIL ICQ   Вверх
artsb
Дата 25.4.2009, 09:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Я бы сохранил её в поток и отправил. Потом принял и прочитал из потока.


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Sharkfire
Дата 25.4.2009, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 236
Регистрация: 30.11.2006
Где: Одесса

Репутация: 2
Всего: 2



подскажи код пожалуйста !
PM MAIL ICQ   Вверх
artsb
Дата 25.4.2009, 17:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Хм... не нашёл у TidUDPClient метода WriteStream . А уTidTCPClient он есть...
Ну да ладно.
Попробуйте так:
Код

// устанавливаем соединение
TMemoryStream *ms = new TMemoryStream();
// запись в поток
IdUDPClient1->Send(&(ms->Size), sizeof(__int64)); // отправляем размер потока
ms->Position = 0;
IdUDPClient1->Send(ms->Memory, ms->Size); // отправляем поток
ms->Clear();
delete ms;
// разрываем соединение

Хотя я так не пробовал...

Либо отправляйте по частям:
Код

// на клиенте
struct MyStruct
{
  AnsiString Str;
  int d;
  float k;
} st;
int Size;
// открываем соединение
// отправляем команду, кторая на сервере будет означать, что сейчас "идёт" структура
Size = st.Str.Length();
IdUDPClient1->SendBuffer(&Size, sizeof(int)); // отправляем длину строки
IdUDPClient1->Send(st.Str.c_str(), Size); // отправляем строку
IdUDPClient1->SendBuffer(&(st.d), sizeof(int)); // отправляем d
IdUDPClient1->SendBuffer(&(st.k), sizeof(float)); // отправляем k
// закрываем соединение

// на сервере
struct MyStruct
{
  AnsiString Str;
  int d;
  float k;
} st;
int Size;
// получаем команду, кторая означает, что сейчас "идёт" структура
AData->ReadBuffer(&Size, sizeof(int)); // получаем длину строки
char *Buff = new char[Size + 1];
AData->ReadBuffer(Buff, Size); //  читаем строку
st.Str = Buff;
delete Buff;
AData->ReceiveBuffer(&(st.d), sizeof(int), -1); // читаем d
AData->ReceiveBuffer(&(st.k), sizeof(float), -1); // читаем k


Это сообщение отредактировал(а) artsb - 25.4.2009, 18:13


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Sharkfire
Дата 26.4.2009, 19:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 236
Регистрация: 30.11.2006
Где: Одесса

Репутация: 2
Всего: 2



Я видел как то просто отправляли структура (в одном примере) просто там как параметры был указатель а не TByteDynArray.
мне так проще пременные послать подугому.... ((

разве нет других вариантов ?
PM MAIL ICQ   Вверх
artsb
Дата 26.4.2009, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Вот пример:
Код

struct MyStruct
{
  AnsiString Str;
  int d;
  float k;
};
MyStruct* st;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
st = new MyStruct;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormDestroy(TObject *Sender)
{
delete st;
}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{

st->Str = NULL;
st->Str = Edit1->Text;
st->d = Edit2->Text.ToInt();
st->k = Edit3->Text.ToDouble();
int Size;
Size = sizeof(int);
Size += sizeof(float);
Size += st->Str.Length();
// по идеи, здесь надо отправить размер структуры:
// IdUDPClient1->SendBuffer(&Size, sizeof(int));
IdUDPClient1->SendBuffer(st, Size); // отправляем структуру
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdUDPServer1UDPRead(TObject *Sender,
      TStream *AData, TIdSocketHandle *ABinding)
{
MyStruct* st2 = new MyStruct;
int Size;
// здесь надо бы получить размер структуры:
// AData->ReadBuffer(&Size, sizeof(int));
AData->ReadBuffer(st2, 13); // здесь, вместо 13 надо писать Size
Label2->Caption = st2->Str;
Label3->Caption = IntToStr(st2->d);
Label4->Caption = FloatToStr(st2->k);
delete st2;
}

Этот пример работает. Но только со структурой статического размера. По идеи, надо отправить сначала размер структуры, а потом саму структуру. А на сервере - получить размер структуры, а уже потом читать её.
IdUDP работает не так как IdTCP. Там было просто:
Код

// отправка
IdTCPClient1->SendBuffer(&Size, sizeof(int)); // размер
IdTCPClient1->SendBuffer(st, Size); // структура
// приём
AThread->Connection->ReadBuffer(&Size, sizeof(int)); // размер
AThread->Connection->ReadBuffer(st2, Size); // структура

А вот с IdUDP такое не прокатывает. При таком коде:
Код

// отправка
IdUDPClient1->SendBuffer(&Size, sizeof(int));
IdUDPClient1->SendBuffer(st, Size); 
// приём
AData->ReadBuffer(&Size, sizeof(int));
AData->ReadBuffer(st2, 13); 

отправляется и то, и то. А вот приход только размер, т.е. AData->Size = 4. Ну естественно, при попытке прочитать что-то после чтения размера, вылетает экскепшин.
Есть подозрение, что за раз приходит только одна порция отправленных данных. По идее, структура придёт позже smile Будем ждать...  smile 

В общем, тут надо что-то придумывать, либо юзать IdTCP.

Это сообщение отредактировал(а) artsb - 26.4.2009, 21:57


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Sharkfire
Дата 5.5.2009, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 236
Регистрация: 30.11.2006
Где: Одесса

Репутация: 2
Всего: 2



Хорошо, а как мне выбрать оптимальный размер БУФЕРА для передачи?

К примеру я кусочками передаю файл, мне надо подобрать такой размер буфера что бы максимально нагрузить канал ....
PM MAIL ICQ   Вверх
Sharkfire
Дата 5.5.2009, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 236
Регистрация: 30.11.2006
Где: Одесса

Репутация: 2
Всего: 2



Дело в том, что у меня версия Indy вообще не содержит в себе SendBuffer(void *,int size), есть SendBuffer(String IP,int Port,TByteDynArray data)


Вот что я написал, по моей задаче
Код

 TMemoryStream *ms = new TMemoryStream();
 short int struct_type=0;//"тип" пакета
 ms->Write(&struct_type,sizeof(short int));//записали
 short int protocol_version=1;//версия нашего протокола
 ms->Write(&protocol_version,sizeof(short int));//записали
 //уникальный id слота (всегда 16 символов)
 ms->Write(_newSlot->SlotUID.c_str(),sizeof(_newSlot->SlotUID.operator [](0))*16+1);
 //псевдоним стороны
 String _nik="Default";
 //пишем размер псевдонима
 int len = _nik.Length();
 ms->Write(&len,sizeof(int));
 //сам псевдоним
 ms->Write(_nik.c_str(),sizeof(_nik.operator [](0))*_nik.Length()+1);

 TByteDynArray dynArray;
 ms->Position=0;
 //ЗДЕСЬ ms ПЕРЕВОДИМ В dynArray
 UDPClient->SendBuffer(_newSlot->IP,4502,dynArray);



(поправьте, если что не так)

И осталось заменить строку " //ЗДЕСЬ ms ПЕРЕВОДИМ В dynArray" на что-то, а на что именно не подскажете? 

PM MAIL ICQ   Вверх
artsb
Дата 5.5.2009, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Цитата(Sharkfire @  5.5.2009,  12:53 Найти цитируемый пост)
а как мне выбрать оптимальный размер БУФЕРА для передачи?

Об этом не парьтесь. Учитывая то, какие сейчас машины, имхо, это роли не играет. размер буфера влияет на то, сколько оперативки будет жрать Indy. Ведь при отправке инфы, она её на самом деле не отправляет до тех пор, пока не наполнится полный буфер. Только после наполнения, весь буфер отправляется и после чего - очищается.

Цитата

Дело в том, что у меня версия Indy вообще не содержит в себе SendBuffer(void *,int size), есть SendBuffer(String IP,int Port,TByteDynArray data)

Хм... Не может быть. Что у вас за версия?
А вы не пробовали так:
Код

TMemoryStream *ms = new TMemoryStream();
// запись в поток
IdUDPClient1->Send(&(ms->Size), sizeof(__int64)); // отправляем размер потока
ms->Position = 0;
IdUDPClient1->Send(ms->Memory, ms->Size); // отправляем поток
ms->Clear();
delete ms;

Опять таки, в случае с UDP тяжелее организовать приём данных. Надо подумать...

ЗЫ а почему именно UDP? Почему не TCP?

Это сообщение отредактировал(а) artsb - 5.5.2009, 22:12


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Sharkfire
Дата 6.5.2009, 18:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 236
Регистрация: 30.11.2006
Где: Одесса

Репутация: 2
Всего: 2



У меня та что идёт с 2009-м Быдлем тобишь... 11-ая вроде ?

Та я вот уже сам задумываюсь может всё такие перейти на TCP дело в том что надо передавать довольно большие файлы по сети
и там буду всякие зависания (блокирующиеся сокеты и т.п.)
Передавать надо в несколько независимых каналов (потоков) и ещё и то туда то обатно.

Добавлено через 2 минуты и 54 секунды
user posted image
PM MAIL ICQ   Вверх
artsb
Дата 6.5.2009, 20:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Цитата(Sharkfire @  6.5.2009,  18:56 Найти цитируемый пост)
буду всякие зависания (блокирующиеся сокеты и т.п.)

На сколько я помню, у Indy есть компонент IdAntifreeze. Он вроде как борется с этим.


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0892 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.