📄 groupsockhelper.cpp.save
字号:
return curSize;}unsigned getSendBufferSize(UsageEnvironment& env, int socket) { return getBufferSize(env, SO_SNDBUF, socket);}unsigned getReceiveBufferSize(UsageEnvironment& env, int socket) { return getBufferSize(env, SO_RCVBUF, socket);}static unsigned setBufferTo(UsageEnvironment& env, int bufOptName, int socket, unsigned requestedSize) { SOCKLEN_T sizeSize = sizeof requestedSize; setsockopt(socket, SOL_SOCKET, bufOptName, (char*)&requestedSize, sizeSize); // Get and return the actual, resulting buffer size: return getBufferSize(env, bufOptName, socket);}unsigned setSendBufferTo(UsageEnvironment& env, int socket, unsigned requestedSize) { return setBufferTo(env, SO_SNDBUF, socket, requestedSize);}unsigned setReceiveBufferTo(UsageEnvironment& env, int socket, unsigned requestedSize) { return setBufferTo(env, SO_RCVBUF, socket, requestedSize);}static unsigned increaseBufferTo(UsageEnvironment& env, int bufOptName, int socket, unsigned requestedSize) { // First, get the current buffer size. If it's already at least // as big as what we're requesting, do nothing. unsigned curSize = getBufferSize(env, bufOptName, socket); // Next, try to increase the buffer to the requested size, // or to some smaller size, if that's not possible: while (requestedSize > curSize) { SOCKLEN_T sizeSize = sizeof requestedSize; if (setsockopt(socket, SOL_SOCKET, bufOptName, (char*)&requestedSize, sizeSize) >= 0) { // success return requestedSize; } requestedSize = (requestedSize+curSize)/2; } return getBufferSize(env, bufOptName, socket);}unsigned increaseSendBufferTo(UsageEnvironment& env, int socket, unsigned requestedSize) { return increaseBufferTo(env, SO_SNDBUF, socket, requestedSize);}unsigned increaseReceiveBufferTo(UsageEnvironment& env, int socket, unsigned requestedSize) { return increaseBufferTo(env, SO_RCVBUF, socket, requestedSize);}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;}Boolean socketLeaveGroup(UsageEnvironment&, 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_DROP_MEMBERSHIP, (const char*)&imr, sizeof (struct ip_mreq)) < 0) { return False; } return True;}// The source-specific join/leave operations require special setsockopt()// commands, and a special structure (ip_mreq_source). If the include files// didn't define these, we do so here:#ifndef IP_ADD_SOURCE_MEMBERSHIP#ifdef LINUX#define IP_ADD_SOURCE_MEMBERSHIP 39#define IP_DROP_SOURCE_MEMBERSHIP 40#else#define IP_ADD_SOURCE_MEMBERSHIP 67#define IP_DROP_SOURCE_MEMBERSHIP 68#endifstruct ip_mreq_source { struct in_addr imr_multiaddr; /* IP multicast address of group */ struct in_addr imr_sourceaddr; /* IP address of source */ struct in_addr imr_interface; /* local IP address of interface */};#endifBoolean socketJoinGroupSSM(UsageEnvironment& env, int socket, netAddressBits groupAddress, netAddressBits sourceFilterAddr) { if (!IsMulticastAddress(groupAddress)) return True; // ignore this case struct ip_mreq_source imr; imr.imr_multiaddr.s_addr = groupAddress; imr.imr_sourceaddr.s_addr = sourceFilterAddr; imr.imr_interface.s_addr = ReceivingInterfaceAddr; if (setsockopt(socket, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, (const char*)&imr, sizeof (struct ip_mreq_source)) < 0) { socketErr(env, "setsockopt(IP_ADD_SOURCE_MEMBERSHIP) error: "); return False; } return True;}Boolean socketLeaveGroupSSM(UsageEnvironment& /*env*/, int socket, netAddressBits groupAddress, netAddressBits sourceFilterAddr) { if (!IsMulticastAddress(groupAddress)) return True; // ignore this case struct ip_mreq_source imr; imr.imr_multiaddr.s_addr = groupAddress; imr.imr_sourceaddr.s_addr = sourceFilterAddr; imr.imr_interface.s_addr = ReceivingInterfaceAddr; if (setsockopt(socket, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP, (const char*)&imr, sizeof (struct ip_mreq_source)) < 0) { return False; } return True;}static Boolean getSourcePort0(int socket, portNumBits& resultPortNum/*host order*/) { sockaddr_in test; test.sin_port = 0; SOCKLEN_T len = sizeof test; if (getsockname(socket, (struct sockaddr*)&test, &len) < 0) return False; resultPortNum = ntohs(test.sin_port); return True;}Boolean getSourcePort(UsageEnvironment& env, int socket, Port& port) { portNumBits portNum = 0; if (!getSourcePort0(socket, portNum) || portNum == 0) { // Hack - call bind(), then try again: struct sockaddr_in name; name.sin_family = AF_INET; name.sin_port = 0; name.sin_addr.s_addr = INADDR_ANY; bind(socket, (struct sockaddr*)&name, sizeof name); if (!getSourcePort0(socket, portNum) || portNum == 0) { socketErr(env, "getsockname() error: "); return False; } } port = Port(portNum); return True;}static Boolean badAddress(netAddressBits addr) { // Check for some possible erroneous addresses: netAddressBits hAddr = ntohl(addr); return (hAddr == 0x7F000001 /* 127.0.0.1 */ || hAddr == 0 || hAddr == (netAddressBits)(~0));}Boolean loopbackWorks = 1;netAddressBits ourSourceAddressForMulticast(UsageEnvironment& env) { static netAddressBits ourAddress = 0; int sock = -1; struct in_addr testAddr; if (ourAddress == 0) { // We need to find our source address struct sockaddr_in fromAddr; // Get our address by sending a (0-TTL) multicast packet, // receiving it, and looking at the source address used. // (This is kinda bogus, but it provides the best guarantee // that other nodes will think our address is the same as we do.) do { loopbackWorks = 0; // until we learn otherwise testAddr.s_addr = our_inet_addr("228.67.43.91"); // arbitrary Port testPort(15947); // ditto sock = setupDatagramSocket(env, testPort); if (sock < 0) break; if (!socketJoinGroup(env, sock, testAddr.s_addr)) break; unsigned char testString[] = "hostIdTest"; unsigned testStringLength = sizeof testString; if (!writeSocket(env, sock, testAddr, testPort, 0, testString, testStringLength)) break; unsigned char readBuffer[20]; struct timeval timeout; timeout.tv_sec = 5; timeout.tv_usec = 0; int bytesRead = readSocket(env, sock, readBuffer, sizeof readBuffer, fromAddr, &timeout); if (bytesRead == 0 // timeout occurred || bytesRead != (int)testStringLength || strncmp((char*)readBuffer, (char*)testString, testStringLength) != 0) { break; } loopbackWorks = 1; } while (0); if (!loopbackWorks) do { // We couldn't find our address using multicast loopback // so try instead to look it up directly. char hostname[100]; hostname[0] = '\0';#ifndef CRIS gethostname(hostname, sizeof hostname);#endif if (hostname[0] == '\0') { env.setResultErrMsg("initial gethostname() failed"); break; } #if defined(VXWORKS)#include <hostLib.h> if (ERROR == (ourAddress = hostGetByName( hostname ))) break;#else struct hostent* hstent = (struct hostent*)gethostbyname(hostname); if (hstent == NULL || hstent->h_length != 4) { env.setResultErrMsg("initial gethostbyname() failed"); break; } // Take the first address that's not bad // (This code, like many others, won't handle IPv6) netAddressBits addr = 0; for (unsigned i = 0; ; ++i) { char* addrPtr = hstent->h_addr_list[i]; if (addrPtr == NULL) break; netAddressBits a = *(netAddressBits*)addrPtr; if (!badAddress(a)) { addr = a; break; } } if (addr != 0) { fromAddr.sin_addr.s_addr = addr; } else { env.setResultMsg("no address"); break; } } while (0); // Make sure we have a good address: netAddressBits from = fromAddr.sin_addr.s_addr; if (badAddress(from)) { char tmp[100]; sprintf(tmp, "This computer has an invalid IP address: 0x%x", (netAddressBits)(ntohl(from))); env.setResultMsg(tmp); from = 0; } ourAddress = from;#endif if (sock >= 0) { socketLeaveGroup(env, sock, testAddr.s_addr); closeSocket(sock); } // Use our newly-discovered IP address, and the current time, // to initialize the random number generator's seed: struct timeval timeNow; gettimeofday(&timeNow, NULL); unsigned seed = ourAddress^timeNow.tv_sec^timeNow.tv_usec; our_srandom(seed); } return ourAddress;}netAddressBits chooseRandomIPv4SSMAddress(UsageEnvironment& env) { // First, a hack to ensure that our random number generator is seeded: (void) ourSourceAddressForMulticast(env); // Choose a random address in the range [232.0.1.0, 232.255.255.255) // i.e., [0xE8000100, 0xE8FFFFFF) netAddressBits const first = 0xE8000100, lastPlus1 = 0xE8FFFFFF; netAddressBits const range = lastPlus1 - first; return htonl(first + ((netAddressBits)our_random())%range);}char const* timestampString() { struct timeval tvNow; gettimeofday(&tvNow, NULL); static char timeString[9]; // holds hh:mm:ss plus trailing '\0' char const* ctimeResult = ctime((time_t*)&tvNow.tv_sec); char const* from = &ctimeResult[11]; int i; for (i = 0; i < 8; ++i) { timeString[i] = from[i]; } timeString[i] = '\0'; return (char const*)&timeString;}#if (defined(__WIN32__) || defined(_WIN32)) && !defined(IMN_PIM)// For Windoze, we need to implement our own gettimeofday()#if !defined(_WIN32_WCE)#include <sys/timeb.h>#endifint gettimeofday(struct timeval* tp, int* /*tz*/) {#if defined(_WIN32_WCE) /* FILETIME of Jan 1 1970 00:00:00. */ static const unsigned __int64 epoch = 116444736000000000L; FILETIME file_time; SYSTEMTIME system_time; ULARGE_INTEGER ularge; GetSystemTime(&system_time); SystemTimeToFileTime(&system_time, &file_time); ularge.LowPart = file_time.dwLowDateTime; ularge.HighPart = file_time.dwHighDateTime; tp->tv_sec = (long) ((ularge.QuadPart - epoch) / 10000000L); tp->tv_usec = (long) (system_time.wMilliseconds * 1000);#else struct timeb tb; ftime(&tb); tp->tv_sec = tb.time; tp->tv_usec = 1000*tb.millitm;#endif return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -