См. функцию 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()