int Socket::send( unsigned char *inBuffer, int inNumBytes, char inAllowedToBlock, char inAllowDelay ) { unsigned int *socketIDptr = (unsigned int *)( mNativeObjectPointer ); unsigned int socketID = socketIDptr[0]; if( inAllowedToBlock ) { if( ! inAllowDelay ) { // turn nodelay on setNoDelay( 1 ); } int returnVal = ::send( socketID, (char*)inBuffer, inNumBytes, 0 ); if( ! inAllowDelay ) { // turn nodelay back off setNoDelay( 0 ); } return returnVal; } else { // 1 for non-blocking, 0 for blocking u_long socketMode = 1; ioctlsocket( socketID, FIONBIO, &socketMode ); if( ! inAllowDelay ) { // turn nodelay on setNoDelay( 1 ); } int result = ::send( socketID, (char*)inBuffer, inNumBytes, 0 ); if( ! inAllowDelay ) { // turn nodelay back off setNoDelay( 0 ); } // set back to blocking socketMode = 0; ioctlsocket( socketID, FIONBIO, &socketMode ); if( result == -1 && WSAGetLastError() == WSAEWOULDBLOCK ) { return -2; } else { return result; } } }
/* * Accept a connection. This will block waiting for somebody to show up. */ bool jdwpAcceptConnection(NetState* netState) { struct sockaddr_in addr; socklen_t addrlen; int sock; if (netState->listenSock < 0) return false; /* you're not listening! */ assert(netState->dbg.sock < 0); /* must not already be talking */ addrlen = sizeof(addr); do { sock = accept(netState->listenSock, (struct sockaddr*) &addr, &addrlen); if (sock < 0 && errno != EINTR) { fprintf(stderr, "accept failed: %s\n", strerror(errno)); return false; } } while (sock < 0); fprintf(stderr, "+++ accepted connection from %s:%u\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); netState->dbg.sock = sock; netState->dbg.awaitingHandshake = true; netState->dbg.inputCount = 0; setNoDelay(sock); return true; }
void TSocket::setSocketOptions(const Options& options) { // Connect timeout options_.connTimeout = options.connTimeout; // Send timeout if (options.sendTimeout >= 0) { setSendTimeout(options.sendTimeout); } // Recv timeout if (options.recvTimeout >= 0) { setRecvTimeout(options.recvTimeout); } // Send Buffer Size if (options.sendBufSize > 0) { setSendBufSize(options.sendBufSize); } // Recv Buffer Size if (options.recvBufSize > 0) { setRecvBufSize(options.recvBufSize); } // Linger setLinger(options.lingerOn, options.lingerVal); // No delay setNoDelay(options.noDelay); setReuseAddress(options.reuseAddr); }
TCPSocket::TCPSocket(const Address& address, TCPSocketObserver *o) throw(NetworkException) : SocketBase(address,true), observer(o) { doConnect(); setNoDelay(); }
/* * Connect to the VM. */ bool jdwpConnectToVm(NetState* netState) { struct sockaddr_in addr; int sock = -1; sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock < 0) { fprintf(stderr, "Socket create failed: %s\n", strerror(errno)); goto fail; } addr.sin_family = AF_INET; addr.sin_addr = netState->vmAddr; addr.sin_port = htons(netState->vmPort); if (connect(sock, (struct sockaddr*) &addr, sizeof(addr)) != 0) { fprintf(stderr, "Connection to %s:%u failed: %s\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), strerror(errno)); goto fail; } fprintf(stderr, "+++ connected to VM %s:%u\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); netState->vm.sock = sock; netState->vm.awaitingHandshake = true; netState->vm.inputCount = 0; setNoDelay(netState->vm.sock); return true; fail: if (sock >= 0) close(sock); return false; }
bool TransportTCP::initializeSocket() { ROS_ASSERT(sock_ != ROS_INVALID_SOCKET); if (!setNonBlocking()) { return false; } setKeepAlive(s_use_keepalive_, 60, 10, 9); // connect() will set cached_remote_host_ because it already has the host/port available if (cached_remote_host_.empty()) { if (is_server_) { cached_remote_host_ = "TCPServer Socket"; } else { std::stringstream ss; ss << getClientURI() << " on socket " << sock_; cached_remote_host_ = ss.str(); } } if (local_port_ < 0) { la_len_ = s_use_ipv6_ ? sizeof(sockaddr_in6) : sizeof(sockaddr_in); getsockname(sock_, (sockaddr *)&local_address_, &la_len_); switch (local_address_.ss_family) { case AF_INET: local_port_ = ntohs(((sockaddr_in *)&local_address_)->sin_port); break; case AF_INET6: local_port_ = ntohs(((sockaddr_in6 *)&local_address_)->sin6_port); break; } } #ifdef ROSCPP_USE_TCP_NODELAY setNoDelay(true); #endif ROS_ASSERT(poll_set_ || (flags_ & SYNCHRONOUS)); if (poll_set_) { ROS_DEBUG("Adding tcp socket [%d] to pollset", sock_); poll_set_->addSocket(sock_, boost::bind(&TransportTCP::socketUpdate, this, _1), shared_from_this()); } if (!(flags_ & SYNCHRONOUS)) { //enableRead(); } return true; }
void TransportTCP::parseHeader(const Header& header) { std::string nodelay; if (header.getValue("tcp_nodelay", nodelay) && nodelay == "1") { ROSCPP_LOG_DEBUG("Setting nodelay on socket [%d]", sock_); setNoDelay(true); } }
/** Returns -1 if no data, else char from getchar **/ char getcharNoWait() { if(initialized == false) setNoDelay(); if(lastChar >= 0) { char c = lastChar; lastChar = -1; return c; } return getchar(); }
void TCPSocket::onResolved() { SocketBase::onResolved(); create(); setNonBlocking(); setConfigured(); doConnect(); setNoDelay(); }
/* * Accept a connection. This will block waiting for somebody to show up. * If that's not desirable, use checkConnection() to make sure something * is pending. */ static bool acceptConnection(JdwpState* state) { JdwpNetState* netState = state->netState; union { struct sockaddr_in addrInet; struct sockaddr addrPlain; } addr; socklen_t addrlen; int sock; if (netState->listenSock < 0) return false; /* you're not listening! */ assert(netState->clientSock < 0); /* must not already be talking */ addrlen = sizeof(addr); do { sock = accept(netState->listenSock, &addr.addrPlain, &addrlen); if (sock < 0 && errno != EINTR) { // When we call shutdown() on the socket, accept() returns with // EINVAL. Don't gripe about it. if (errno == EINVAL) LOGVV("accept failed: %s", strerror(errno)); else ALOGE("accept failed: %s", strerror(errno)); return false; } } while (sock < 0); netState->remoteAddr = addr.addrInet.sin_addr; netState->remotePort = ntohs(addr.addrInet.sin_port); ALOGV("+++ accepted connection from %s:%u", inet_ntoa(netState->remoteAddr), netState->remotePort); netState->clientSock = sock; netState->awaitingHandshake = true; netState->inputCount = 0; ALOGV("Setting TCP_NODELAY on accepted socket"); setNoDelay(netState->clientSock); if (pipe(netState->wakePipe) < 0) { ALOGE("pipe failed"); return false; } return true; }
bool TransportTCP::initializeSocket() { ROS_ASSERT(sock_ != ROS_INVALID_SOCKET); if (!setNonBlocking()) { return false; } setKeepAlive(s_use_keepalive_, 60, 10, 9); // connect() will set cached_remote_host_ because it already has the host/port available if (cached_remote_host_.empty()) { if (is_server_) { cached_remote_host_ = "TCPServer Socket"; } else { std::stringstream ss; ss << getClientURI() << " on socket " << sock_; cached_remote_host_ = ss.str(); } } #ifdef ROSCPP_USE_TCP_NODELAY setNoDelay(true); #endif ROS_ASSERT(poll_set_ || (flags_ & SYNCHRONOUS)); if (poll_set_) { ROS_DEBUG("Adding tcp socket [%d] to pollset", sock_); poll_set_->addSocket(sock_, boost::bind(&TransportTCP::socketUpdate, this, _1), shared_from_this()); } if (!(flags_ & SYNCHRONOUS)) { //enableRead(); } return true; }
bool CMySocket::ConnectServer() { Close(); m_bfirstpack = true; m_bZlib = false; m_zlibIn.Init(); m_zlibDe.Init(); m_sRecvBuf.clear(); struct sockaddr_in peer; if (!set_address(m_szdomian, m_port, &peer)) { g_WriteLog.WriteLog(C_LOG_ERROR, "set_address error, domain:%s, port:%hd", m_szdomian, m_port); return FALSE; } SOCKET s = socket(AF_INET, SOCK_STREAM, 0); if (s == INVALID_SOCKET) { int nerrid = WSAGetLastError(); g_WriteLog.WriteLog(C_LOG_ERROR, "create sock error, errno=%d, %s", errno, FormatLastError(nerrid)); return FALSE; } if (connect(s, (struct sockaddr *)&peer, sizeof(peer))) { int nerrid = WSAGetLastError(); g_WriteLog.WriteLog(C_LOG_ERROR, "connect to %s:%hu,errno=%d, %s", m_szdomian, m_port, errno, FormatLastError(nerrid)); closesocket(s); s = INVALID_SOCKET; return FALSE; } setNonblock(s); setNoDelay(s, true); m_hSocket = s; //赋值后导致recv线程开始执行 return m_hSocket != INVALID_SOCKET; }
void ClientSocket::connect(const Ip &ip, int port) { sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(ip.getString().c_str()); addr.sin_port = htons(port); int res = ::connect(sock, reinterpret_cast<const sockaddr*>(&addr), sizeof(addr)); if (res == SOCKET_ERROR) { int errCode = get_error(); if (errCode != WOULD_BLOCK) { handleError(__FUNCTION__); } else { // TODO // wait a bit, check writable, try again cout << "::connect() error, WOULD_BLOCK.\n"; } } else { setNoDelay(); } }
bool isCharReady() { if(initialized == false) setNoDelay(); if(lastChar >= 0) return true; lastChar = getchar(); return (lastChar >= 0); }
void Settings_Interpret( char option, const char *optarg, thread_Settings *mExtSettings ) { char outarg[100]; switch ( option ) { case '1': // Single Client setSingleClient( mExtSettings ); break; case 'b': // UDP bandwidth #ifdef RINA if ( !isUDP( mExtSettings ) && !isRINA( mExtSettings ) ) { #else if ( !isUDP( mExtSettings ) ) { #endif fprintf( stderr, warn_implied_udp, option ); } if ( mExtSettings->mThreadMode != kMode_Client ) { fprintf( stderr, warn_invalid_server_option, option ); break; } Settings_GetLowerCaseArg(optarg,outarg); mExtSettings->mUDPRate = byte_atoi(outarg); #ifdef RINA if ( !isUDP( mExtSettings ) && !isRINA( mExtSettings ) ) #endif setUDP( mExtSettings ); // if -l has already been processed, mBufLenSet is true // so don't overwrite that value. if ( !isBuflenSet( mExtSettings ) ) { mExtSettings->mBufLen = kDefault_UDPBufLen; } break; case 'c': // client mode w/ server host to connect to mExtSettings->mHost = new char[ strlen( optarg ) + 1 ]; strcpy( mExtSettings->mHost, optarg ); if ( mExtSettings->mThreadMode == kMode_Unknown ) { // Test for Multicast iperf_sockaddr temp; SockAddr_setHostname( mExtSettings->mHost, &temp, (isIPV6( mExtSettings ) ? 1 : 0 )); if ( SockAddr_isMulticast( &temp ) ) { setMulticast( mExtSettings ); } mExtSettings->mThreadMode = kMode_Client; mExtSettings->mThreads = 1; } break; case 'd': // Dual-test Mode #ifdef RINA if ( isRINA( mExtSettings ) ) { fprintf( stderr, warn_invalid_rina_option, option ); break; } #endif if ( mExtSettings->mThreadMode != kMode_Client ) { fprintf( stderr, warn_invalid_server_option, option ); break; } if ( isCompat( mExtSettings ) ) { fprintf( stderr, warn_invalid_compatibility_option, option ); } #ifdef HAVE_THREAD mExtSettings->mMode = kTest_DualTest; #else fprintf( stderr, warn_invalid_single_threaded, option ); mExtSettings->mMode = kTest_TradeOff; #endif break; case 'f': // format to print in mExtSettings->mFormat = (*optarg); break; case 'h': // print help and exit fprintf(stderr, usage_long1); fprintf(stderr, usage_long2); exit(1); break; case 'i': // specify interval between periodic bw reports mExtSettings->mInterval = atof( optarg ); if ( mExtSettings->mInterval < 0.5 ) { fprintf (stderr, report_interval_small, mExtSettings->mInterval); mExtSettings->mInterval = 0.5; } break; case 'l': // length of each buffer Settings_GetUpperCaseArg(optarg,outarg); mExtSettings->mBufLen = byte_atoi( outarg ); setBuflenSet( mExtSettings ); #ifdef RINA if ( !isUDP( mExtSettings ) && !isRINA( mExtSettings ) ) { #else if ( !isUDP( mExtSettings ) ) { #endif if ( mExtSettings->mBufLen < (int) sizeof( client_hdr ) && !isCompat( mExtSettings ) ) { setCompat( mExtSettings ); fprintf( stderr, warn_implied_compatibility, option ); } } else { if ( mExtSettings->mBufLen < (int) sizeof( UDP_datagram ) ) { mExtSettings->mBufLen = sizeof( UDP_datagram ); fprintf( stderr, warn_buffer_too_small, mExtSettings->mBufLen ); } if ( !isCompat( mExtSettings ) && mExtSettings->mBufLen < (int) ( sizeof( UDP_datagram ) + sizeof( client_hdr ) ) ) { setCompat( mExtSettings ); fprintf( stderr, warn_implied_compatibility, option ); } } break; case 'm': // print TCP MSS setPrintMSS( mExtSettings ); break; case 'n': // bytes of data // amount mode (instead of time mode) unsetModeTime( mExtSettings ); Settings_GetUpperCaseArg(optarg,outarg); mExtSettings->mAmount = byte_atoi( outarg ); break; case 'o' : // output the report and other messages into the file unsetSTDOUT( mExtSettings ); mExtSettings->mOutputFileName = new char[strlen(optarg)+1]; strcpy( mExtSettings->mOutputFileName, optarg); break; case 'p': // server port mExtSettings->mPort = atoi( optarg ); break; case 'r': // test mode tradeoff if ( mExtSettings->mThreadMode != kMode_Client ) { fprintf( stderr, warn_invalid_server_option, option ); break; } if ( isCompat( mExtSettings ) ) { fprintf( stderr, warn_invalid_compatibility_option, option ); } mExtSettings->mMode = kTest_TradeOff; break; case 's': // server mode #ifdef RINA if ( mExtSettings->mThreadMode != kMode_Unknown && !isRINA( mExtSettings ) ) { #else if ( mExtSettings->mThreadMode != kMode_Unknown ) { #endif fprintf( stderr, warn_invalid_client_option, option ); break; } mExtSettings->mThreadMode = kMode_Listener; break; case 't': // seconds to write for // time mode (instead of amount mode) setModeTime( mExtSettings ); mExtSettings->mAmount = (int) (atof( optarg ) * 100.0); break; case 'u': // UDP instead of TCP // if -b has already been processed, UDP rate will // already be non-zero, so don't overwrite that value if ( !isUDP( mExtSettings ) ) { setUDP( mExtSettings ); #ifdef RINA unsetRINA( mExtSettings ); #endif mExtSettings->mUDPRate = kDefault_UDPRate; } // if -l has already been processed, mBufLenSet is true // so don't overwrite that value. if ( !isBuflenSet( mExtSettings ) ) { mExtSettings->mBufLen = kDefault_UDPBufLen; } else if ( mExtSettings->mBufLen < (int) ( sizeof( UDP_datagram ) + sizeof( client_hdr ) ) && !isCompat( mExtSettings ) ) { setCompat( mExtSettings ); fprintf( stderr, warn_implied_compatibility, option ); } break; case 'v': // print version and exit fprintf( stderr, version ); exit(1); break; case 'w': // TCP window size (socket buffer size) Settings_GetUpperCaseArg(optarg,outarg); mExtSettings->mTCPWin = byte_atoi(outarg); if ( mExtSettings->mTCPWin < 2048 ) { fprintf( stderr, warn_window_small, mExtSettings->mTCPWin ); } break; case 'x': // Limit Reports while ( *optarg != '\0' ) { switch ( *optarg ) { case 's': case 'S': setNoSettReport( mExtSettings ); break; case 'c': case 'C': setNoConnReport( mExtSettings ); break; case 'd': case 'D': setNoDataReport( mExtSettings ); break; case 'v': case 'V': setNoServReport( mExtSettings ); break; case 'm': case 'M': setNoMultReport( mExtSettings ); break; default: fprintf(stderr, warn_invalid_report, *optarg); } optarg++; } break; case 'y': // Reporting Style switch ( *optarg ) { case 'c': case 'C': mExtSettings->mReportMode = kReport_CSV; break; default: fprintf( stderr, warn_invalid_report_style, optarg ); } break; // more esoteric options #ifdef RINA case 'A': // RINA instead of UDP or TCP mExtSettings->mMode = kTest_Normal; // RINA don't work in dual mode setRINA( mExtSettings ); // if -b has already been processed, UDP rate will // already be non-zero, so don't overwrite that value if ( isUDP( mExtSettings ) ) { unsetUDP( mExtSettings ); } else { mExtSettings->mUDPRate = kDefault_UDPRate; } // if -l has already been processed, mBufLenSet is true // so don't overwrite that value. if ( !isBuflenSet( mExtSettings ) ) { mExtSettings->mBufLen = kDefault_UDPBufLen; } else if ( mExtSettings->mBufLen < (int) ( sizeof( UDP_datagram ) + sizeof( client_hdr ) ) && !isCompat( mExtSettings ) ) { setCompat( mExtSettings ); fprintf( stderr, warn_implied_compatibility, option ); } // if -s have not been used yet, consider the use of client mode if ( mExtSettings->mThreadMode == kMode_Unknown ) { mExtSettings->mThreadMode = kMode_Client; } rina::initialize("EMERG", ""); break; #endif case 'B': // specify bind address mExtSettings->mLocalhost = new char[ strlen( optarg ) + 1 ]; strcpy( mExtSettings->mLocalhost, optarg ); // Test for Multicast iperf_sockaddr temp; SockAddr_setHostname( mExtSettings->mLocalhost, &temp, (isIPV6( mExtSettings ) ? 1 : 0 )); if ( SockAddr_isMulticast( &temp ) ) { setMulticast( mExtSettings ); } break; case 'C': // Run in Compatibility Mode setCompat( mExtSettings ); if ( mExtSettings->mMode != kTest_Normal ) { fprintf( stderr, warn_invalid_compatibility_option, ( mExtSettings->mMode == kTest_DualTest ? 'd' : 'r' ) ); mExtSettings->mMode = kTest_Normal; } break; case 'D': // Run as a daemon setDaemon( mExtSettings ); break; case 'F' : // Get the input for the data stream from a file if ( mExtSettings->mThreadMode != kMode_Client ) { fprintf( stderr, warn_invalid_server_option, option ); break; } setFileInput( mExtSettings ); mExtSettings->mFileName = new char[strlen(optarg)+1]; strcpy( mExtSettings->mFileName, optarg); break; case 'I' : // Set the stdin as the input source if ( mExtSettings->mThreadMode != kMode_Client ) { fprintf( stderr, warn_invalid_server_option, option ); break; } setFileInput( mExtSettings ); setSTDIN( mExtSettings ); mExtSettings->mFileName = new char[strlen("<stdin>")+1]; strcpy( mExtSettings->mFileName,"<stdin>"); break; case 'L': // Listen Port (bidirectional testing client-side) if ( mExtSettings->mThreadMode != kMode_Client ) { fprintf( stderr, warn_invalid_server_option, option ); break; } mExtSettings->mListenPort = atoi( optarg ); break; case 'M': // specify TCP MSS (maximum segment size) Settings_GetUpperCaseArg(optarg,outarg); mExtSettings->mMSS = byte_atoi( outarg ); break; case 'N': // specify TCP nodelay option (disable Jacobson's Algorithm) setNoDelay( mExtSettings ); break; case 'P': // number of client threads #ifdef HAVE_THREAD mExtSettings->mThreads = atoi( optarg ); #else if ( mExtSettings->mThreadMode != kMode_Server ) { fprintf( stderr, warn_invalid_single_threaded, option ); } else { mExtSettings->mThreads = atoi( optarg ); } #endif break; case 'R': setRemoveService( mExtSettings ); break; case 'S': // IP type-of-service // TODO use a function that understands base-2 // the zero base here allows the user to specify // "0x#" hex, "0#" octal, and "#" decimal numbers mExtSettings->mTOS = strtol( optarg, NULL, 0 ); break; case 'T': // time-to-live for multicast mExtSettings->mTTL = atoi( optarg ); break; case 'U': // single threaded UDP server setSingleUDP( mExtSettings ); break; case 'V': // IPv6 Domain setIPV6( mExtSettings ); if ( mExtSettings->mThreadMode == kMode_Server && mExtSettings->mLocalhost != NULL ) { // Test for Multicast iperf_sockaddr temp; SockAddr_setHostname( mExtSettings->mLocalhost, &temp, 1); if ( SockAddr_isMulticast( &temp ) ) { setMulticast( mExtSettings ); } } else if ( mExtSettings->mThreadMode == kMode_Client ) { // Test for Multicast iperf_sockaddr temp; SockAddr_setHostname( mExtSettings->mHost, &temp, 1 ); if ( SockAddr_isMulticast( &temp ) ) { setMulticast( mExtSettings ); } } break; case 'W' : setSuggestWin( mExtSettings ); fprintf( stderr, "The -W option is not available in this release\n"); break; case 'Z': #ifdef TCP_CONGESTION setCongestionControl( mExtSettings ); mExtSettings->mCongestion = new char[strlen(optarg)+1]; strcpy( mExtSettings->mCongestion, optarg); #else fprintf( stderr, "The -Z option is not available on this operating system\n"); #endif break; default: // ignore unknown break; } } // end Interpret void Settings_GetUpperCaseArg(const char *inarg, char *outarg) { int len = strlen(inarg); strcpy(outarg,inarg); if ( (len > 0) && (inarg[len-1] >='a') && (inarg[len-1] <= 'z') ) outarg[len-1]= outarg[len-1]+'A'-'a'; } void Settings_GetLowerCaseArg(const char *inarg, char *outarg) { int len = strlen(inarg); strcpy(outarg,inarg); if ( (len > 0) && (inarg[len-1] >='A') && (inarg[len-1] <= 'Z') ) outarg[len-1]= outarg[len-1]-'A'+'a'; } /* * Settings_GenerateListenerSettings * Called to generate the settings to be passed to the Listener * instance that will handle dual testings from the client side * this should only return an instance if it was called on * the thread_Settings instance generated from the command line * for client side execution */ void Settings_GenerateListenerSettings( thread_Settings *client, thread_Settings **listener ) { if ( !isCompat( client ) && (client->mMode == kTest_DualTest || client->mMode == kTest_TradeOff) ) { *listener = new thread_Settings; memcpy(*listener, client, sizeof( thread_Settings )); setCompat( (*listener) ); unsetDaemon( (*listener) ); if ( client->mListenPort != 0 ) { (*listener)->mPort = client->mListenPort; } else { (*listener)->mPort = client->mPort; } (*listener)->mFileName = NULL; (*listener)->mHost = NULL; (*listener)->mLocalhost = NULL; (*listener)->mOutputFileName = NULL; (*listener)->mMode = kTest_Normal; (*listener)->mThreadMode = kMode_Listener; if ( client->mHost != NULL ) { (*listener)->mHost = new char[strlen( client->mHost ) + 1]; strcpy( (*listener)->mHost, client->mHost ); } if ( client->mLocalhost != NULL ) { (*listener)->mLocalhost = new char[strlen( client->mLocalhost ) + 1]; strcpy( (*listener)->mLocalhost, client->mLocalhost ); } } else { *listener = NULL; } } /* * Settings_GenerateSpeakerSettings * Called to generate the settings to be passed to the Speaker * instance that will handle dual testings from the server side * this should only return an instance if it was called on * the thread_Settings instance generated from the command line * for server side execution. This should be an inverse operation * of GenerateClientHdr. */ void Settings_GenerateClientSettings( thread_Settings *server, thread_Settings **client, client_hdr *hdr ) { int flags = ntohl(hdr->flags); if ( (flags & HEADER_VERSION1) != 0 ) { *client = new thread_Settings; memcpy(*client, server, sizeof( thread_Settings )); setCompat( (*client) ); (*client)->mTID = thread_zeroid(); (*client)->mPort = (unsigned short) ntohl(hdr->mPort); (*client)->mThreads = ntohl(hdr->numThreads); if ( hdr->bufferlen != 0 ) { (*client)->mBufLen = ntohl(hdr->bufferlen); } if ( hdr->mWinBand != 0 ) { #ifdef RINA if ( isUDP( server ) || isRINA( server ) ) { #else if ( isUDP( server ) ) { #endif (*client)->mUDPRate = ntohl(hdr->mWinBand); } else { (*client)->mTCPWin = ntohl(hdr->mWinBand); } } (*client)->mAmount = ntohl(hdr->mAmount); if ( ((*client)->mAmount & 0x80000000) > 0 ) { setModeTime( (*client) ); #ifndef WIN32 (*client)->mAmount |= 0xFFFFFFFF00000000LL; #else (*client)->mAmount |= 0xFFFFFFFF00000000; #endif (*client)->mAmount = -(*client)->mAmount; } (*client)->mFileName = NULL; (*client)->mHost = NULL; (*client)->mLocalhost = NULL; (*client)->mOutputFileName = NULL; (*client)->mMode = ((flags & RUN_NOW) == 0 ? kTest_TradeOff : kTest_DualTest); (*client)->mThreadMode = kMode_Client; if ( server->mLocalhost != NULL ) { (*client)->mLocalhost = new char[strlen( server->mLocalhost ) + 1]; strcpy( (*client)->mLocalhost, server->mLocalhost ); } (*client)->mHost = new char[REPORT_ADDRLEN]; if ( ((sockaddr*)&server->peer)->sa_family == AF_INET ) { inet_ntop( AF_INET, &((sockaddr_in*)&server->peer)->sin_addr, (*client)->mHost, REPORT_ADDRLEN); } #ifdef HAVE_IPV6 else { inet_ntop( AF_INET6, &((sockaddr_in6*)&server->peer)->sin6_addr, (*client)->mHost, REPORT_ADDRLEN); } #endif } else { *client = NULL; } } /* * Settings_GenerateClientHdr * Called to generate the client header to be passed to the * server that will handle dual testings from the server side * This should be an inverse operation of GenerateSpeakerSettings */ void Settings_GenerateClientHdr( thread_Settings *client, client_hdr *hdr ) { if ( client->mMode != kTest_Normal ) { hdr->flags = htonl(HEADER_VERSION1); } else { hdr->flags = 0; } if ( isBuflenSet( client ) ) { hdr->bufferlen = htonl(client->mBufLen); } else { hdr->bufferlen = 0; } #ifdef RINA if ( isUDP( client ) || isRINA( client ) ) { #else if ( isUDP( client ) ) { #endif hdr->mWinBand = htonl(client->mUDPRate); } else { hdr->mWinBand = htonl(client->mTCPWin); } if ( client->mListenPort != 0 ) { hdr->mPort = htonl(client->mListenPort); } else { hdr->mPort = htonl(client->mPort); } hdr->numThreads = htonl(client->mThreads); if ( isModeTime( client ) ) { hdr->mAmount = htonl(-(long)client->mAmount); } else { hdr->mAmount = htonl((long)client->mAmount); hdr->mAmount &= htonl( 0x7FFFFFFF ); } if ( client->mMode == kTest_DualTest ) { hdr->flags |= htonl(RUN_NOW); } }
void Settings_Interpret( char option, const char *optarg, thread_Settings *mExtSettings ) { char outarg[100]; switch ( option ) { case '1': // Single Client setSingleClient( mExtSettings ); break; case 'b': // UDP bandwidth if ( !isUDP( mExtSettings ) ) { fprintf( stderr, warn_implied_udp, option ); } if ( mExtSettings->mThreadMode != kMode_Client ) { fprintf( stderr, warn_invalid_server_option, option ); break; } Settings_GetLowerCaseArg(optarg,outarg); mExtSettings->mUDPRate = byte_atoi(outarg); setUDP( mExtSettings ); // if -l has already been processed, mBufLenSet is true // so don't overwrite that value. if ( !isBuflenSet( mExtSettings ) ) { mExtSettings->mBufLen = kDefault_UDPBufLen; } break; case 'c': // client mode w/ server host to connect to mExtSettings->mHost = new char[ strlen( optarg ) + 1 ]; strcpy( mExtSettings->mHost, optarg ); if ( mExtSettings->mThreadMode == kMode_Unknown ) { // Test for Multicast iperf_sockaddr temp; SockAddr_setHostname( mExtSettings->mHost, &temp, (isIPV6( mExtSettings ) ? 1 : 0 )); if ( SockAddr_isMulticast( &temp ) ) { setMulticast( mExtSettings ); } mExtSettings->mThreadMode = kMode_Client; mExtSettings->mThreads = 1; } break; case 'd': // Dual-test Mode if ( mExtSettings->mThreadMode != kMode_Client ) { fprintf( stderr, warn_invalid_server_option, option ); break; } if ( isCompat( mExtSettings ) ) { fprintf( stderr, warn_invalid_compatibility_option, option ); } #ifdef HAVE_THREAD mExtSettings->mMode = kTest_DualTest; #else fprintf( stderr, warn_invalid_single_threaded, option ); mExtSettings->mMode = kTest_TradeOff; #endif break; case 'f': // format to print in mExtSettings->mFormat = (*optarg); break; case 'h': // print help and exit fprintf(stderr, usage_long1); fprintf(stderr, usage_long2); exit(1); break; case 'i': // specify interval between periodic bw reports mExtSettings->mInterval = atof( optarg ); if ( mExtSettings->mInterval < 0.5 ) { fprintf (stderr, report_interval_small, mExtSettings->mInterval); mExtSettings->mInterval = 0.5; } break; case 'l': // length of each buffer Settings_GetUpperCaseArg(optarg,outarg); mExtSettings->mBufLen = byte_atoi( outarg ); setBuflenSet( mExtSettings ); if ( !isUDP( mExtSettings ) ) { if ( mExtSettings->mBufLen < (int) sizeof( client_hdr ) && !isCompat( mExtSettings ) ) { setCompat( mExtSettings ); fprintf( stderr, warn_implied_compatibility, option ); } } else { if ( mExtSettings->mBufLen < (int) sizeof( UDP_datagram ) ) { mExtSettings->mBufLen = sizeof( UDP_datagram ); fprintf( stderr, warn_buffer_too_small, mExtSettings->mBufLen ); } if ( !isCompat( mExtSettings ) && mExtSettings->mBufLen < (int) ( sizeof( UDP_datagram ) + sizeof( client_hdr ) ) ) { setCompat( mExtSettings ); fprintf( stderr, warn_implied_compatibility, option ); } } break; case 'm': // print TCP MSS setPrintMSS( mExtSettings ); break; case 'n': // bytes of data // amount mode (instead of time mode) unsetModeTime( mExtSettings ); Settings_GetUpperCaseArg(optarg,outarg); mExtSettings->mAmount = byte_atoi( outarg ); break; case 'o' : // output the report and other messages into the file unsetSTDOUT( mExtSettings ); mExtSettings->mOutputFileName = new char[strlen(optarg)+1]; strcpy( mExtSettings->mOutputFileName, optarg); break; case 'p': // server port mExtSettings->mPort = atoi( optarg ); break; case 'r': // test mode tradeoff if ( mExtSettings->mThreadMode != kMode_Client ) { fprintf( stderr, warn_invalid_server_option, option ); break; } if ( isCompat( mExtSettings ) ) { fprintf( stderr, warn_invalid_compatibility_option, option ); } mExtSettings->mMode = kTest_TradeOff; break; case 's': // server mode if ( mExtSettings->mThreadMode != kMode_Unknown ) { fprintf( stderr, warn_invalid_client_option, option ); break; } mExtSettings->mThreadMode = kMode_Listener; break; case 't': // seconds to write for // time mode (instead of amount mode) setModeTime( mExtSettings ); mExtSettings->mAmount = (int) (atof( optarg ) * 100.0); break; case 'u': // UDP instead of TCP // if -b has already been processed, UDP rate will // already be non-zero, so don't overwrite that value if ( !isUDP( mExtSettings ) ) { setUDP( mExtSettings ); mExtSettings->mUDPRate = kDefault_UDPRate; } // if -l has already been processed, mBufLenSet is true // so don't overwrite that value. if ( !isBuflenSet( mExtSettings ) ) { mExtSettings->mBufLen = kDefault_UDPBufLen; } else if ( mExtSettings->mBufLen < (int) ( sizeof( UDP_datagram ) + sizeof( client_hdr ) ) && !isCompat( mExtSettings ) ) { setCompat( mExtSettings ); fprintf( stderr, warn_implied_compatibility, option ); } break; case 'v': // print version and exit fprintf( stderr, version ); exit(1); break; case 'w': // TCP window size (socket buffer size) Settings_GetUpperCaseArg(optarg,outarg); mExtSettings->mTCPWin = byte_atoi(outarg); if ( mExtSettings->mTCPWin < 2048 ) { fprintf( stderr, warn_window_small, mExtSettings->mTCPWin ); } break; case 'x': // Limit Reports while ( *optarg != '\0' ) { switch ( *optarg ) { case 's': case 'S': setNoSettReport( mExtSettings ); break; case 'c': case 'C': setNoConnReport( mExtSettings ); break; case 'd': case 'D': setNoDataReport( mExtSettings ); break; case 'v': case 'V': setNoServReport( mExtSettings ); break; case 'm': case 'M': setNoMultReport( mExtSettings ); break; default: fprintf(stderr, warn_invalid_report, *optarg); } optarg++; } break; case 'y': // Reporting Style switch ( *optarg ) { case 'c': case 'C': mExtSettings->mReportMode = kReport_CSV; break; default: fprintf( stderr, warn_invalid_report_style, optarg ); } break; // more esoteric options case 'E': // specify the local port on this PC to connect with (only for client mode) mExtSettings->mLocalPort = atoi( optarg ); break; case 'B': // specify bind address mExtSettings->mLocalhost = new char[ strlen( optarg ) + 1 ]; strcpy( mExtSettings->mLocalhost, optarg ); // Test for Multicast iperf_sockaddr temp; SockAddr_setHostname( mExtSettings->mLocalhost, &temp, (isIPV6( mExtSettings ) ? 1 : 0 )); if ( SockAddr_isMulticast( &temp ) ) { setMulticast( mExtSettings ); } break; case 'C': // Run in Compatibility Mode setCompat( mExtSettings ); if ( mExtSettings->mMode != kTest_Normal ) { fprintf( stderr, warn_invalid_compatibility_option, ( mExtSettings->mMode == kTest_DualTest ? 'd' : 'r' ) ); mExtSettings->mMode = kTest_Normal; } break; case 'D': // Run as a daemon setDaemon( mExtSettings ); break; case 'F' : // Get the input for the data stream from a file if ( mExtSettings->mThreadMode != kMode_Client ) { fprintf( stderr, warn_invalid_server_option, option ); break; } setFileInput( mExtSettings ); mExtSettings->mFileName = new char[strlen(optarg)+1]; strcpy( mExtSettings->mFileName, optarg); break; case 'I' : // Set the stdin as the input source if ( mExtSettings->mThreadMode != kMode_Client ) { fprintf( stderr, warn_invalid_server_option, option ); break; } setFileInput( mExtSettings ); setSTDIN( mExtSettings ); mExtSettings->mFileName = new char[strlen("<stdin>")+1]; strcpy( mExtSettings->mFileName,"<stdin>"); break; case 'L': // Listen Port (bidirectional testing client-side) if ( mExtSettings->mThreadMode != kMode_Client ) { fprintf( stderr, warn_invalid_server_option, option ); break; } mExtSettings->mListenPort = atoi( optarg ); break; case 'M': // specify TCP MSS (maximum segment size) Settings_GetUpperCaseArg(optarg,outarg); mExtSettings->mMSS = byte_atoi( outarg ); break; case 'N': // specify TCP nodelay option (disable Jacobson's Algorithm) setNoDelay( mExtSettings ); break; case 'P': // number of client threads #ifdef HAVE_THREAD mExtSettings->mThreads = atoi( optarg ); #else if ( mExtSettings->mThreadMode != kMode_Server ) { fprintf( stderr, warn_invalid_single_threaded, option ); } else { mExtSettings->mThreads = atoi( optarg ); } #endif break; case 'R': setRemoveService( mExtSettings ); break; case 'S': // IP type-of-service // TODO use a function that understands base-2 // the zero base here allows the user to specify // "0x#" hex, "0#" octal, and "#" decimal numbers mExtSettings->mTOS = strtol( optarg, NULL, 0 ); break; case 'T': // time-to-live for multicast mExtSettings->mTTL = atoi( optarg ); break; case 'U': // single threaded UDP server setSingleUDP( mExtSettings ); break; case 'V': // IPv6 Domain setIPV6( mExtSettings ); if ( mExtSettings->mThreadMode == kMode_Server && mExtSettings->mLocalhost != NULL ) { // Test for Multicast iperf_sockaddr temp; SockAddr_setHostname( mExtSettings->mLocalhost, &temp, 1); if ( SockAddr_isMulticast( &temp ) ) { setMulticast( mExtSettings ); } } else if ( mExtSettings->mThreadMode == kMode_Client ) { // Test for Multicast iperf_sockaddr temp; SockAddr_setHostname( mExtSettings->mHost, &temp, 1 ); if ( SockAddr_isMulticast( &temp ) ) { setMulticast( mExtSettings ); } } break; case 'W' : setSuggestWin( mExtSettings ); fprintf( stderr, "The -W option is not available in this release\n"); break; case 'Z': #ifdef TCP_CONGESTION setCongestionControl( mExtSettings ); mExtSettings->mCongestion = new char[strlen(optarg)+1]; strcpy( mExtSettings->mCongestion, optarg); #else fprintf( stderr, "The -Z option is not available on this operating system\n"); #endif break; default: // ignore unknown break; } } // end Interpret
int MprSocket::openServer(char *addr, int portNum, MprSocketAcceptProc acceptFn, void *data, int initialFlags) { #if BLD_FEATURE_IPV6 struct addrinfo hints, *res; struct sockaddr_storage sockAddr6; char portNumString[MPR_MAX_IP_PORT]; char addrBuf[MPR_MAX_IP_ADDR]; char *bindName; #endif struct sockaddr_in sockAddr; struct sockaddr *sa; struct hostent *hostent; MprSocklen addrlen; int datagram, rc; mprAssert(addr); if (addr == 0 || *addr == '\0') { mprLog(6, log, "openServer: *:%d, flags %x\n", portNum, initialFlags); } else { mprLog(6, log, "openServer: %s:%d, flags %x\n", addr, portNum, initialFlags); } #if BLD_FEATURE_IPV6 if (addr[0] == '[') { ipv6 = 1; mprStrcpy(addrBuf, sizeof(addrBuf), &addr[1]); mprAssert(addrBuf[strlen(addrBuf) - 1] == ']'); addrBuf[strlen(addrBuf) - 1] = '\0'; addr = addrBuf; } if (ipv6) { memset((char *) &hints, '\0', sizeof(hints)); memset((char *) &sockAddr6, '\0', sizeof(struct sockaddr_storage)); mprSprintf(portNumString, sizeof(portNumString), "%d", portNum); hints.ai_socktype = SOCK_STREAM; hints.ai_family = AF_INET6; if (strcmp(addr, "") != 0) { bindName = addr; } else { bindName = NULL; hints.ai_flags |= AI_PASSIVE; /* Bind to 0.0.0.0 and :: */ /* Sets to IN6ADDR_ANY_INIT */ } rc = getaddrinfo(bindName, portNumString, &hints, &res); if (rc) { return MPR_ERR_CANT_OPEN; } sa = (struct sockaddr*) &sockAddr6; memcpy(sa, res->ai_addr, res->ai_addrlen); addrlen = res->ai_addrlen; freeaddrinfo(res); } else #endif { /* * TODO could we use getaddrinfo in all cases. ie. merge with IPV6 code */ memset((char *) &sockAddr, '\0', sizeof(struct sockaddr_in)); addrlen = sizeof(struct sockaddr_in); sockAddr.sin_family = AF_INET; sockAddr.sin_port = htons((short) (portNum & 0xFFFF)); if (strcmp(addr, "") != 0) { sockAddr.sin_addr.s_addr = inet_addr(addr); if (sockAddr.sin_addr.s_addr == INADDR_NONE) { hostent = mprGetHostByName(addr); if (hostent != 0) { memcpy((char*) &sockAddr.sin_addr, (char*) hostent->h_addr_list[0], (size_t) hostent->h_length); mprFreeGetHostByName(hostent); } else { return MPR_ERR_NOT_FOUND; } } } else { sockAddr.sin_addr.s_addr = INADDR_ANY; } sa = (struct sockaddr*) &sockAddr; } lock(); port = portNum; acceptCallback = acceptFn; acceptData = data; flags = (initialFlags & (MPR_SOCKET_BROADCAST | MPR_SOCKET_DATAGRAM | MPR_SOCKET_BLOCK | MPR_SOCKET_LISTENER | MPR_SOCKET_NOREUSE | MPR_SOCKET_NODELAY)); ipAddr = mprStrdup(addr); datagram = flags & MPR_SOCKET_DATAGRAM; // // Create the O/S socket // sock = socket(sa->sa_family, datagram ? SOCK_DGRAM: SOCK_STREAM, 0); if (sock < 0) { unlock(); return MPR_ERR_CANT_OPEN; } #if !WIN && !WINCE && !VXWORKS fcntl(sock, F_SETFD, FD_CLOEXEC); // Children won't inherit this fd #endif #if CYGWIN || LINUX || MACOSX || VXWORKS || FREEBSD if (!(flags & MPR_SOCKET_NOREUSE)) { rc = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &rc, sizeof(rc)); } #endif rc = bind(sock, sa, addrlen); // rc = bind(sock, res->ai_addr, res->ai_addrlen); if (rc < 0) { int err = errno; err = err; ::closesocket(sock); sock = -1; unlock(); return MPR_ERR_CANT_OPEN; } if (! datagram) { flags |= MPR_SOCKET_LISTENER; if (listen(sock, SOMAXCONN) < 0) { ::closesocket(sock); sock = -1; unlock(); return MPR_ERR_CANT_OPEN; } handler = new MprSelectHandler(sock, MPR_SOCKET_READABLE, (MprSelectProc) acceptProcWrapper, (void*) this, handlerPriority); } handlerMask |= MPR_SOCKET_READABLE; //TODO - what about WINCE? #if WIN // // Delay setting reuse until now so that we can be assured that we // have exclusive use of the port. // if (!(flags & MPR_SOCKET_NOREUSE)) { rc = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &rc, sizeof(rc)); } #endif setBlockingMode((bool) (flags & MPR_SOCKET_BLOCK)); // // TCP/IP stacks have the No delay option (nagle algorithm) on by default. // if (flags & MPR_SOCKET_NODELAY) { setNoDelay(1); } unlock(); return sock; }
/* * Create a connection to a waiting debugger. */ static bool establishConnection(JdwpState* state) { union { struct sockaddr_in addrInet; struct sockaddr addrPlain; } addr; struct hostent* pEntry; int h_errno; assert(state != NULL && state->netState != NULL); assert(!state->params.server); assert(state->params.host[0] != '\0'); assert(state->params.port != 0); /* * Start by resolving the host name. */ //#undef HAVE_GETHOSTBYNAME_R //#warning "forcing non-R" #ifdef HAVE_GETHOSTBYNAME_R struct hostent he; char auxBuf[128]; int cc = gethostbyname_r(state->params.host, &he, auxBuf, sizeof(auxBuf), &pEntry, &h_errno); if (cc != 0) { ALOGW("gethostbyname_r('%s') failed: %s", state->params.host, strerror(errno)); return false; } #else h_errno = 0; pEntry = gethostbyname(state->params.host); if (pEntry == NULL) { ALOGW("gethostbyname('%s') failed: %s", state->params.host, strerror(h_errno)); return false; } #endif /* copy it out ASAP to minimize risk of multithreaded annoyances */ memcpy(&addr.addrInet.sin_addr, pEntry->h_addr, pEntry->h_length); addr.addrInet.sin_family = pEntry->h_addrtype; addr.addrInet.sin_port = htons(state->params.port); ALOGI("Connecting out to '%s' %d", inet_ntoa(addr.addrInet.sin_addr), ntohs(addr.addrInet.sin_port)); /* * Create a socket. */ JdwpNetState* netState; netState = state->netState; netState->clientSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (netState->clientSock < 0) { ALOGE("Unable to create socket: %s", strerror(errno)); return false; } /* * Try to connect. */ if (connect(netState->clientSock, &addr.addrPlain, sizeof(addr)) != 0) { ALOGE("Unable to connect to %s:%d: %s", inet_ntoa(addr.addrInet.sin_addr), ntohs(addr.addrInet.sin_port), strerror(errno)); close(netState->clientSock); netState->clientSock = -1; return false; } ALOGI("Connection established to %s (%s:%d)", state->params.host, inet_ntoa(addr.addrInet.sin_addr), ntohs(addr.addrInet.sin_port)); netState->awaitingHandshake = true; netState->inputCount = 0; setNoDelay(netState->clientSock); if (pipe(netState->wakePipe) < 0) { ALOGE("pipe failed"); return false; } return true; }
int MprSocket::openClient(char *addr, int portNum, int initialFlags) { #if BLD_FEATURE_IPV6 struct addrinfo hints, *res; struct sockaddr_storage remoteAddr6; char portNum_string[MPR_MAX_IP_PORT]; char addrBuf[MPR_MAX_IP_ADDR]; #endif struct sockaddr_in remoteAddr; struct hostent *hostent; struct sockaddr *sa; MprSocklen addrlen; int broadcast, datagram, rc, err; mprLog(6, log, "openClient: %s:%d, flags %x\n", addr, portNum, initialFlags); #if BLD_FEATURE_IPV6 if (addr[0] == '[') { ipv6 = 1; mprStrcpy(addrBuf, sizeof(addr), &addr[1]); mprAssert(addrBuf[strlen(addrBuf) - 2] == ']'); addrBuf[strlen(addrBuf) - 2] = '\0'; addr = addrBuf; } else { ipv6 = 0; } if (ipv6) { memset((char*) &hints, '\0', sizeof(hints)); memset((char*) &remoteAddr6, '\0', sizeof(struct sockaddr_storage)); mprSprintf(portNum_string, sizeof(portNum_string), "%d", portNum); hints.ai_socktype = SOCK_STREAM; rc = getaddrinfo(addr, portNum_string, &hints, &res); if (rc) { /* no need to unlock yet */ return MPR_ERR_CANT_OPEN; } sa = (struct sockaddr*) &remoteAddr6; memcpy(sa, res->ai_addr, res->ai_addrlen); addrlen = res->ai_addrlen; freeaddrinfo(res); } else #endif { memset((char *) &remoteAddr, '\0', sizeof(struct sockaddr_in)); remoteAddr.sin_family = AF_INET; remoteAddr.sin_port = htons((short) (portNum & 0xFFFF)); sa = (struct sockaddr*) &remoteAddr; addrlen = sizeof(remoteAddr); } lock(); port = portNum; flags = (initialFlags & (MPR_SOCKET_BROADCAST | MPR_SOCKET_DATAGRAM | MPR_SOCKET_BLOCK | MPR_SOCKET_LISTENER | MPR_SOCKET_NOREUSE | MPR_SOCKET_NODELAY)); // Save copy of the address ipAddr = mprStrdup(addr); #if BLD_FEATURE_IPV6 if (!ipv6) { // Nothing here } else #endif { remoteAddr.sin_addr.s_addr = inet_addr(ipAddr); if (remoteAddr.sin_addr.s_addr == INADDR_NONE) { hostent = mprGetHostByName(ipAddr); if (hostent != 0) { memcpy((char*) &remoteAddr.sin_addr, (char*) hostent->h_addr_list[0], (size_t) hostent->h_length); mprFreeGetHostByName(hostent); } else { unlock(); return MPR_ERR_NOT_FOUND; } } } broadcast = flags & MPR_SOCKET_BROADCAST; if (broadcast) { flags |= MPR_SOCKET_DATAGRAM; } datagram = flags & MPR_SOCKET_DATAGRAM; // // Create the O/S socket // sock = socket(sa->sa_family, datagram ? SOCK_DGRAM: SOCK_STREAM, 0); if (sock < 0) { err = getError(); unlock(); return -err; } #if !WIN && !WINCE && !VXWORKS fcntl(sock, F_SETFD, FD_CLOEXEC); // Children won't inherit this fd #endif if (broadcast) { int flag = 1; if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *) &flag, sizeof(flag)) < 0) { err = getError(); ::closesocket(sock); sock = -1; unlock(); return -err; } } if (!datagram) { flags |= MPR_SOCKET_CONNECTING; rc = connect(sock, sa, addrlen); if (rc < 0) { err = getError(); ::closesocket(sock); sock = -1; unlock(); #if UNUSED // // If the listen backlog is too high, ECONNREFUSED is returned // if (err == EADDRINUSE || err == ECONNREFUSED) { return MPR_ERR_BUSY; } #endif return -err; } } setBlockingMode((bool) (flags & MPR_SOCKET_BLOCK)); // // TCP/IP stacks have the No delay option (nagle algorithm) on by default. // if (flags & MPR_SOCKET_NODELAY) { setNoDelay(1); } unlock(); return sock; }