int readSocket(UsageEnvironment& env, int socket, unsigned char* buffer, unsigned bufferSize, struct sockaddr_in& fromAddress, struct timeval* timeout) { int bytesRead = -1; do { int result = blockUntilReadable(env, socket, timeout); if (timeout != NULL && result == 0) { bytesRead = 0; break; } else if (result <= 0) { break; } SOCKLEN_T addressSize = sizeof fromAddress; bytesRead = recvfrom(socket, (char*)buffer, bufferSize, 0, (struct sockaddr*)&fromAddress, &addressSize); if (bytesRead < 0) { //##### HACK to work around bugs in Linux and Windows: int err = env.getErrno(); if (err == 111 /*ECONNREFUSED (Linux)*/ #if defined(__WIN32__) || defined(_WIN32) // What a piece of crap Windows is. Sometimes // recvfrom() returns -1, but with an 'errno' of 0. // This appears not to be a real error; just treat // it as if it were a read of zero bytes, and hope // we don't have to do anything else to 'reset' // this alleged error: || err == 0 #else || err == EAGAIN #endif || err == 113 /*EHOSTUNREACH (Linux)*/) { //Why does Linux return this for datagram sock? fromAddress.sin_addr.s_addr = 0; return 0; } //##### END HACK socketErr(env, "recvfrom() error: "); break; } } while (0); return bytesRead; }
Boolean socketJoinGroup(UsageEnvironment& env, int socket, netAddressBits groupAddress){ if (!IsMulticastAddress(groupAddress)) return True; // ignore this case struct ip_mreq imr; imr.imr_multiaddr.s_addr = groupAddress; imr.imr_interface.s_addr = ReceivingInterfaceAddr; if (setsockopt(socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&imr, sizeof (struct ip_mreq)) < 0) { #if defined(__WIN32__) || defined(_WIN32) if (env.getErrno() != 0) { // That piece-of-shit toy operating system (Windows) sometimes lies // about setsockopt() failing! #endif socketErr(env, "setsockopt(IP_ADD_MEMBERSHIP) error: "); return False; #if defined(__WIN32__) || defined(_WIN32) } #endif } return True; }
static void printErr(UsageEnvironment& env, char const* str = NULL) { if (str != NULL) err(env) << str; env << ": " << strerror(env.getErrno()) << "\n"; }