예제 #1
0
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);
}
예제 #2
0
// Creating an async socket needs to run on the thread you expect to handle the
// socket later. If not, there might be a race condition where requests came
// before the socket exists.
FbossClient NetlinkManager::getFbossClient(
    const std::string& ip,
    const int& port) {
  folly::SocketAddress addr(ip, port);
  auto socket =
      apache::thrift::async::TAsyncSocket::newSocket(eb_, addr, 2000);
  socket->setSendTimeout(5000);
  auto channel = apache::thrift::HeaderClientChannel::newChannel(socket);
  return std::make_unique<FbossCtrlAsyncClient>(std::move(channel));
}
예제 #3
0
        virtual void run() {
            do {
                if (!setSendTimeout(_sockfd, 1)) {
                    LogError("setSendTimeout failed: %d", getLastErrorNo());
                    break;
                }

                if (!setRecvTimeout(_sockfd, 1)) {
                    LogError("setRecvTimeout failed: %d", getLastErrorNo());
                    break;
                }
                HttpRequest httpRequest;
                int recvLen, parsedLength, unparsed = 0;

                while ((_startTime == 0 || time(nullptr) - _startTime <= _timeout) && _requestCount > 0) {
                    recvLen = recv(_sockfd, _recvBuff + unparsed, RECV_BUFFER_SIZE - unparsed, 0);
                    if (recvLen <= 0 && isTimeout()) {
                        LogError("recv returns %d", recvLen);
                        continue;
                    }
                    if (recvLen <= 0) {
                        LogError("recv failed: %d", getLastErrorNo());
                        break;
                    }

                    unparsed += recvLen;
                    parsedLength = httpRequest.parse(_recvBuff);

                    if (parsedLength < 0) {
                        LogError("parsed wrong http protocol format");
                        break;
                    }

                    if (parsedLength == 0) continue;

                    if (parsedLength <= unparsed) {
                        unparsed -= parsedLength;
                        memmove(_recvBuff, _recvBuff + parsedLength, unparsed);
                    }

                    if (httpRequest.readBodyFinished()) {
                        if (_startTime == 0) _startTime = time(nullptr);
                        
                        string connection;
                        if (httpRequest.getHeaderByKey("CONNECTION", connection) && connection == "close") _requestCount = 1;

                        _requestCount--;

                        string response = _httpRequestHandler.handle(httpRequest);
                        if (!_send(response)) {
                            LogError("send http response failed");
                            break;
                        }

                        httpRequest.reset();
                    }
                }
            } while (false);

            if (closeSocket(_sockfd) < 0) {
                LogError("close socket failed: %d", getLastErrorNo());
            }
        }
예제 #4
0
void TcpSocketImpl::connect(struct addrinfo * paddr, const char * host,
                            const char * port, int timeout) {
    assert(-1 == sock);
    sock = HdfsSystem::socket(paddr->ai_family, paddr->ai_socktype,
                              paddr->ai_protocol);

    if (-1 == sock) {
        THROW(HdfsNetworkException,
              "Create socket failed when connect to %s: %s",
              remoteAddr.c_str(), GetSystemErrorInfo(errno));
    }

    if (lingerTimeout >= 0) {
        setLingerTimeoutInternal(lingerTimeout);
    }

#ifdef __linux__
    /*
     * on linux some kernel use SO_SNDTIMEO as connect timeout.
     * It is OK to set a very large value here since the user has its own timeout mechanism.
     */
    setSendTimeout(3600000);
#endif

    try {
        setBlockMode(false);
        disableSigPipe();
        int rc = 0;

        do {
            rc = HdfsSystem::connect(sock, paddr->ai_addr, paddr->ai_addrlen);
        } while (rc < 0 && EINTR == errno && !CheckOperationCanceled());

        if (rc < 0) {
            if (EINPROGRESS != errno && EWOULDBLOCK != errno) {
                if (ETIMEDOUT == errno) {
                    THROW(HdfsTimeoutException, "Connect to \"%s:%s\" timeout",
                          host, port);
                } else {
                    THROW(HdfsNetworkConnectException,
                          "Connect to \"%s:%s\" failed: %s",
                          host, port, GetSystemErrorInfo(errno));
                }
            }

            if (!poll(false, true, timeout)) {
                THROW(HdfsTimeoutException, "Connect to \"%s:%s\" timeout", host, port);
            }

            struct sockaddr peer;

            unsigned int len = sizeof(peer);

            memset(&peer, 0, sizeof(peer));

            if (HdfsSystem::getpeername(sock, &peer, &len)) {
                /*
                 * connect failed, find out the error info.
                 */
                char c;
                rc = HdfsSystem::recv(sock, &c, 1, 0);
                assert(rc < 0);

                if (ETIMEDOUT == errno) {
                    THROW(HdfsTimeoutException, "Connect to \"%s:%s\" timeout",
                          host, port);
                }

                THROW(HdfsNetworkConnectException, "Connect to \"%s:%s\" failed: %s",
                      host, port, GetSystemErrorInfo(errno));
            }
        }

        setBlockMode(true);
    } catch (...) {
        close();
        throw;
    }
}