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); }
// 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)); }
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()); } }
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; } }