GL_basik 0 31 августа, 2006 Опубликовано 31 августа, 2006 · Жалоба Мне здесь пришлось писать интерфейс для сетевого монитора. Вообщем теперь осваиваю winsock. И в связи с этим у меня возникли вопросы. Девайс конфигурируется и передает служебную информацию по UDP. Мне соответсвенно необходимо принимать пакеты посланые этим девайсом. Но протокол UDP это протокол без установки соединения. Соответственно пакет от устройства может придти в любой момент времени. В Winsock я не нашел что либо похожее на прерывание или событие происходящще по поступлению нового пакета. Есть лишь процедура recv, которая, собственно, осуществляет прием данных. Вопрос в следующем, как определить пришел мне пакет или нет? Или может быть это не надо? Вообщем как принять данные по протоколу UDP? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
and_pp 0 4 сентября, 2006 Опубликовано 4 сентября, 2006 · Жалоба См. функцию 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() Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
subver 0 5 сентября, 2006 Опубликовано 5 сентября, 2006 · Жалоба А не проще бросить на форму компонент типа TNMUDP и работать по его событиям? в билдере вроде как давно уже есть наборчик компонентов для этого дела. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
and_pp 0 5 сентября, 2006 Опубликовано 5 сентября, 2006 · Жалоба У родных UDP компонентов билдера есть один общей недостаток - уж очень они любят терять пакеты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
std.denis 0 7 сентября, 2006 Опубликовано 7 сентября, 2006 · Жалоба для CBuilder, Delphi и .NET есть же замечательная библиотека - Indy.Sockets.. очень даже работоспособна Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sqrt 0 7 сентября, 2006 Опубликовано 7 сентября, 2006 (изменено) · Жалоба Мне здесь пришлось писать интерфейс для сетевого монитора. Вообщем теперь осваиваю winsock. И в связи с этим у меня возникли вопросы. ... Вообщем как принять данные по протоколу UDP? Есть хорошее руководство от Beej, перевод здесь: http://www.wasm.ru/print.php?article=socketbybeej После прочтения многие вопросы пропадут. Изменено 7 сентября, 2006 пользователем Sot Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться