Здравствуйте, все!
Пытаюсь сделать приём-передачу широковещательных сообщений по UDP. Фрагменты кода передающей и принимающей сторон привожу ниже, чтобы не прерывать мысль.
Имею следующую проблемку.- Если я запускаю такой код сервера (принимающей стороны) напрямую от кнопки (в OnClick), то программа виснет намертво
... - Подозревая, что функция recvfrom блокирует ход программы, я пробовал впихнуть этот код в поток (Thread). Тогда ничего не виснет, не блокирует, но и ничего не принимает
... Подскажите, пожалуйста, то ли какая-то ошибка в коде (том или другом), то ли сокет надо переводить в какой-нибудь неблокирующий режим, то ли что-то ещё другое?
Заранее спасибо!
Код передающей стороны (клиента):
| Код | procedure Broadcast(OutMsg: PChar); var wData : WSADATA; WorkSocket: TSocket; b: boolean; server_addr: TSockAddrIn; begin if WSAStartup(MAKEWORD(1,1), wData) <> 0 then // Загружаем WinSock begin MessageDlg('Cannot load WinSock',mtError,[mbOk],0); exit; end;
WorkSocket:= socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Создаём сокет
// Переводим сокет в РЕЖИМ ШИРОКОВЕЩАНИЯ b:= true; setsockopt(WorkSocket, SOL_SOCKET, SO_BROADCAST, @b, sizeof(Boolean));
// Заполняем структуру адреса server_addr.sin_addr.s_addr := htonl(INADDR_ANY); server_addr.sin_family := AF_INET; server_addr.sin_port := htons(Port); server_addr.sin_addr.S_addr := inet_addr('255.255.255.255');
// Отправляем сообщение if SendTo(WorkSocket, OutMsg, sizeof(OutMsg), 0, server_addr, sizeof(server_addr)) = SOCKET_ERROR then b:= false;
// Уходим CloseSocket(WorkSocket); WSACleanup; end;
|
Код принимающей стороны (сервера):
| Код | function Recieve: string; var wData : WSADATA; WorkSocket: TSocket; iSize: integer; local_addr, client_addr: TSockAddrIn; Buff: array [0..255] of char; begin if WSAStartup(MAKEWORD(1,1), wData) <> 0 then // Загружаем WinSock begin MessageDlg('Cannot load WinSock',mtError,[mbOk],0); exit; end;
WorkSocket:= socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Создаём сокет
// Заполняем структуру адреса local_addr.sin_addr.s_addr := htonl(INADDR_ANY); local_addr.sin_family := AF_INET; local_addr.sin_port := htons(Port);
//Связываем с локальным адресом if bind(WorkSocket, local_addr, sizeof(local_addr)) = SOCKET_ERROR then begin TestWinSockError('Bind'); // анализ ошибки exit; end;
// Принимаем iSize:= sizeof(client_addr); if recvfrom(WorkSocket,Buff, 255, 0, client_addr, iSize) <> SOCKET_ERROR then Result:= string(Buff);
// Уходим CloseSocket(WorkSocket); WSACleanup; end;
|
|