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); }
/** Receive a raw string (not encoded by msgpack). * This IO call blocks. * We pass the lua_State to avoid mixing thread contexts. */ LuaStackSize lk::Socket::recv(lua_State *L) { if (lua_isnumber(L, 3)) { setRecvTimeout(lua_tonumber(L, 3)); } if (lua_isnumber(L, 2)) { // <self> <num_bytes> [<timeout>] return recvBytes(L, lua_tonumber(L, 2)); } else if (lua_isstring(L, 2)) { // <self> <mode> [<timeout>] const char *mode = lua_tostring(L, 2); if (mode[0] == '*' && mode[1] == 'a') { return recvAll(L); } else if (mode[0] == '*' && mode[1] == 'l') { return recvLine(L); } else { throw dub::Exception("Bad mode to recv (should be '*a' or '*l' but found '%s')", mode); } } // receive a single line (not returning \r or \n). return recvLine(L); return 1; }
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()); } }