Перейти к содержанию
    

Как работать по сети в C Builder?

Мне здесь пришлось писать интерфейс для сетевого монитора. Вообщем теперь осваиваю winsock. И в связи с этим у меня возникли вопросы.

Девайс конфигурируется и передает служебную информацию по UDP. Мне соответсвенно необходимо принимать пакеты посланые этим девайсом. Но протокол UDP это протокол без установки соединения. Соответственно пакет от устройства может придти в любой момент времени. В Winsock я не нашел что либо похожее на прерывание или событие происходящще по поступлению нового пакета. Есть лишь процедура recv, которая, собственно, осуществляет прием данных. Вопрос в следующем, как определить пришел мне пакет или нет? Или может быть это не надо? Вообщем как принять данные по протоколу UDP?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

См. функцию WSAAsyncSelect - она позволяет назначить сообщение при приходе очередного пакета.

 

Вот как это сделано у меня:

void SetEvent(HWND Handle, unsigned int wMsg, long lEvent=FD_READ) {
        WSAAsyncSelect(UDPSocket,Handle,wMsg,lEvent);
    };

 

Далее в описании класса формы описываешь обработку сообщения:

BEGIN_MESSAGE_MAP
    VCL_MESSAGE_HANDLER(0x8F10, TMessage, Mes);
END_MESSAGE_MAP(TForm);

   __fastcall void Mes(TMessage ms);

 

Где 0x8F10 - произвольные код сообщения. Может быть лубым, гдавное, чтобы не совпал с предопределенным системным

 

Ну а в самой программе пишешь как обычно

void __fastcall TFrmOSC::Mes(TMessage Msg)
{
        int addr_len = sizeof(remote_addr);
        int res = recvfrom(UDPSocket,data,len,0,(struct sockaddr FAR*)&remote_addr, (int FAR*)&addr_len);
        addr = remote_addr.sin_addr.S_un.S_addr;
        port = htons((u_short)remote_addr.sin_port);
        int err = WSAGetLastError();

     * * *
}

 

Еще один совет. По умолчанию, размер входного буфера в Windows для сокета равен 8192 байта. Если пакеты будут сыпаться слишком часто, они будут теряться. Лучше всего установить размер буфера побольше. Вот мой кусок кода

 

bool Stoika::SetRxBufferSize(unsigned int bufferSize)
{
   if (bufferSize <= 0) return false;
   unsigned int oldBufferSize = GetRxBufferSize();
   if (setsockopt(UDPSocket, SOL_SOCKET, SO_RCVBUF, (char*)&bufferSize, sizeof(bufferSize)) < 0)
   {
        setsockopt(UDPSocket, SOL_SOCKET, SO_RCVBUF, (char*)&oldBufferSize, sizeof(oldBufferSize));
        return false;
   }
   return true;
}  // end Stoika::SetRxBufferSize()

unsigned int Stoika::GetRxBufferSize()
{
    unsigned int rxBufferSize = 0;
    int len = sizeof(rxBufferSize);
    if (getsockopt(UDPSocket, SOL_SOCKET, SO_RCVBUF, (char*)&rxBufferSize, &len) < 0)
    {
        return 0;
    }
    return ((unsigned int)rxBufferSize);
}  // end Stoika::GetRxBufferSize()

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А не проще бросить на форму компонент типа TNMUDP и работать по его событиям? в билдере вроде как давно уже есть наборчик компонентов для этого дела.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У родных UDP компонентов билдера есть один общей недостаток - уж очень они любят терять пакеты.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

для CBuilder, Delphi и .NET есть же замечательная библиотека - Indy.Sockets..

очень даже работоспособна

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне здесь пришлось писать интерфейс для сетевого монитора. Вообщем теперь осваиваю winsock. И в связи с этим у меня возникли вопросы.

...

Вообщем как принять данные по протоколу UDP?

Есть хорошее руководство от Beej, перевод здесь:

http://www.wasm.ru/print.php?article=socketbybeej

 

После прочтения многие вопросы пропадут.

Изменено пользователем Sot

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...