#include "orkestra_soket_win.hpp" #include #include namespace fiko { bool UdpSoketWin::ac(uint16_t port) { kapat(); WSADATA wd; if (WSAStartup(MAKEWORD(2, 2), &wd) != 0) return false; wsa_ = true; SOCKET s = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (s == INVALID_SOCKET) { kapat(); return false; } BOOL evet = TRUE; ::setsockopt(s, SOL_SOCKET, SO_BROADCAST, (const char*)&evet, sizeof(evet)); ::setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*)&evet, sizeof(evet)); u_long nb = 1; // non-blocking: al() kareyi asla bloklamaz ::ioctlsocket(s, FIONBIO, &nb); sockaddr_in adres{}; adres.sin_family = AF_INET; adres.sin_addr.s_addr = INADDR_ANY; adres.sin_port = htons(port); if (::bind(s, (sockaddr*)&adres, sizeof(adres)) != 0) { ::closesocket(s); kapat(); return false; } soket_ = (uintptr_t)s; port_ = port; acik_ = true; return true; } void UdpSoketWin::kapat() { if (acik_) ::closesocket((SOCKET)soket_); if (wsa_) ::WSACleanup(); soket_ = 0; port_ = 0; acik_ = false; wsa_ = false; } bool UdpSoketWin::gonderYayin(const std::string& veri) { if (!acik_ || veri.size() > 1400) return false; // MTU altı tek datagram (beacon küçük) sockaddr_in hedef{}; hedef.sin_family = AF_INET; hedef.sin_addr.s_addr = INADDR_BROADCAST; hedef.sin_port = htons(port_); return ::sendto((SOCKET)soket_, veri.data(), (int)veri.size(), 0, (sockaddr*)&hedef, sizeof(hedef)) == (int)veri.size(); } bool UdpSoketWin::al(std::string& veri, std::string* kaynakIp) { if (!acik_) return false; char tampon[2048]; sockaddr_in kaynak{}; int kaynakLen = sizeof(kaynak); const int n = ::recvfrom((SOCKET)soket_, tampon, (int)sizeof(tampon), 0, (sockaddr*)&kaynak, &kaynakLen); if (n <= 0) return false; // WSAEWOULDBLOCK dahil — datagram yok veri.assign(tampon, (size_t)n); if (kaynakIp) { char ip[INET_ADDRSTRLEN] = {}; if (::inet_ntop(AF_INET, &kaynak.sin_addr, ip, sizeof(ip))) kaynakIp->assign(ip); else kaynakIp->clear(); } return true; } } // namespace fiko