bool UDPNetworkSocket::sendData(const uint8_t * _data, size_t _dataSize, const IPv4Address & _address) { if (!isOpen()) return false; #ifdef UTIL_HAVE_LIB_SDL2_NET UDPpacket * p = SDLNet_AllocPacket(_dataSize); std::copy(_data, _data + _dataSize, p->data); p->len = _dataSize; p->address = toSDLIPv4Address(_address); int i = SDLNet_UDP_Send(data->udpsock, -1, p); SDLNet_FreePacket(p); p = nullptr; return i > 0; #elif defined(__linux__) || defined(__unix__) || defined(ANDROID) sockaddr_in sockAddr = toSockaddr(_address); ssize_t bytesSent = sendto(data->udpSocket, _data, _dataSize, 0, reinterpret_cast<const sockaddr *> (&sockAddr), sizeof(sockAddr)); if (bytesSent == -1) { int error = errno; WARN(std::string(strerror(error))); return false; } return true; #else return false; #endif }
//! \return number of targets int UDPNetworkSocket::sendData(const uint8_t * _data, size_t _dataSize) { if (!isOpen() || data->targets.empty() ) return 0; int sendCounter = 0; #ifdef UTIL_HAVE_LIB_SDL2_NET UDPpacket * p = SDLNet_AllocPacket(_dataSize); if (p == nullptr) { std::cerr << "SDLNet_AllocPacket: " << SDLNet_GetError() << "\n"; return sendCounter; } std::copy(_data, _data + _dataSize, p->data); p->len = _dataSize; for(const auto & target : data->targets) { p->address = toSDLIPv4Address(target); sendCounter += SDLNet_UDP_Send(data->udpsock, -1, p); } SDLNet_FreePacket(p); p = nullptr; #elif defined(__linux__) || defined(__unix__) || defined(ANDROID) for(const auto & target : data->targets) { sockaddr_in sockAddr = toSockaddr(target); ssize_t bytesSent = sendto(data->udpSocket, _data, _dataSize, 0, reinterpret_cast<const sockaddr *> (&sockAddr), sizeof(sockaddr_in)); if (bytesSent == -1) { int error = errno; WARN(std::string(strerror(error))); } else { ++sendCounter; } } #endif return sendCounter; }
void Win32Network::attachUDPSocket(SOCKET s,const char* netInterface,int port){ sockaddr_in address; setSocketOption(s,ESocketOption::ESO_NONBLOCK,true); setSocketOption(s,ESocketOption::ESO_SOCKOPT_BROADCAST,true); if(!netInterface || !netInterface[0] || !strcmp(netInterface,"localhost")){ //use any available interface address.sin_addr.s_addr=htonl(INADDR_ANY); }else{ NetAddress addr; inner_getHostAddress(netInterface,addr); toSockaddr(addr,(sockaddr*)&address); } if(!port){ address.sin_port=0; }else{ address.sin_port=htons((short)port); } address.sin_family=AF_INET; int len=sizeof(address); //bind address to the socket if(::bind(s,(sockaddr*)&address,len)==-1){ messages::logMessage(messages::HMSG_BIND,ELL_ERROR); return; } }
//## int System.sendto(int socket, Bytes message, int flags, String dstIP, int dstPort, int family); static KMETHOD System_sendto(KonohaContext *kctx, KonohaStack* sfp) { kBytes *ba = sfp[2].asBytes; struct sockaddr_in addr; kString* s = sfp[4].asString; toSockaddr(&addr, (char *)S_text(s), WORD2INT(sfp[5].intValue), WORD2INT(sfp[6].intValue)); // Broken Pipe Signal Mask #if defined(__linux__) __sighandler_t oldset = signal(SIGPIPE, SIG_IGN); __sighandler_t ret_signal = SIG_ERR; #elif defined(__APPLE__) || defined(__NetBSD__) sig_t oldset = signal(SIGPIPE, SIG_IGN); sig_t ret_signal = SIG_ERR; #endif int ret = sendto( WORD2INT(sfp[1].intValue), ba->buf, ba->bytesize, (int)sfp[3].intValue, (struct sockaddr *)&addr, sizeof(struct sockaddr) ); if(ret < 0) { OLDTRACE_SWITCH_TO_KTrace(_SystemFault, LogText("@", "sendto"), LogUint("errno", errno), LogText("errstr", strerror(errno)) ); } if(oldset != SIG_ERR) { ret_signal = signal(SIGPIPE, oldset); if(ret_signal == SIG_ERR) { OLDTRACE_SWITCH_TO_KTrace(_SystemFault, LogText("@", "signal"), LogUint("errno", errno), LogText("errstr", strerror(errno)) ); } } KReturnUnboxValue(ret); }
//## int System.bind(int socket, String srcIP, int srcPort, int family); KMETHOD System_bind(KonohaContext *kctx, KonohaStack* sfp) { struct sockaddr_in addr; toSockaddr(&addr, S_text(sfp[2].asString), WORD2INT(sfp[3].intValue), WORD2INT(sfp[4].intValue) ); int ret = bind(WORD2INT(sfp[1].intValue), (struct sockaddr *)&addr, sizeof(addr) ); if(ret != 0) { OLDTRACE_SWITCH_TO_KTrace(_SystemFault, LogText("@", "bind"), LogUint("errno", errno), LogText("errstr", strerror(errno)) ); } KReturnUnboxValue(ret); }