static ssize_t VectorPush(gnutls_transport_ptr_t transportptr, const giovec_t* iov, int iovcnt) { StreamSocket* sock = reinterpret_cast<StreamSocket*>(transportptr); #ifdef _WIN32 GnuTLSIOHook* session = static_cast<GnuTLSIOHook*>(sock->GetIOHook()); #endif if (sock->GetEventMask() & FD_WRITE_WILL_BLOCK) { #ifdef _WIN32 gnutls_transport_set_errno(session->sess, EAGAIN); #else errno = EAGAIN; #endif return -1; } // Cast the giovec_t to iovec not to IOVector so the correct function is called on Windows int ret = SocketEngine::WriteV(sock, reinterpret_cast<const iovec*>(iov), iovcnt); #ifdef _WIN32 // See the function above for more info about the usage of gnutls_transport_set_errno() on Windows if (ret < 0) gnutls_transport_set_errno(session->sess, SocketEngine::IgnoreError() ? EAGAIN : errno); #endif int size = 0; for (int i = 0; i < iovcnt; i++) size += iov[i].iov_len; if (ret < size) SocketEngine::ChangeEventMask(sock, FD_WRITE_WILL_BLOCK); return ret; }
void *connectMainLoop(void *arg) { StreamSocket *socket = new StreamSocket(); if(socket) { int connectSock; string connectIP; unsigned int port; int ret = socket->startServer(CONNECT_PORT); while(ret >= 0) { connectSock = socket->accept(connectIP, port); if(connectSock != INVALID_SOCKET) { cout <<"connect ip ="<<connectIP<<":"<<port<<endl; socket->setRemoteSocket(connectSock, connectIP, port); createThread(recvDataLoop, (void*)socket); } else { perror("\n connectMainLoop accept socket error: "); usleep(300*1000); // 300ms } } delete(socket); socket = NULL; } return NULL; }
void SocketStreamTest::testEOF() { StreamSocket ss; SocketStream str(ss); { EchoServer echoServer; ss.connect(SocketAddress("localhost", echoServer.port())); str << "hello"; assert (str.good()); str.flush(); assert (str.good()); ss.shutdownSend(); char buffer[5]; str.read(buffer, sizeof(buffer)); assert (str.good()); assert (str.gcount() == 5); assert (std::string(buffer, 5) == "hello"); } int c = str.get(); assert (c == -1); assert (str.eof()); ss.close(); }
void EchoServer::run() { _ready.set(); pi::Timespan span(250000); while (!_stop) { if (_socket.poll(span, Socket::SELECT_READ)) { StreamSocket ss = _socket.acceptConnection(); try { char buffer[256]; int n = ss.receiveBytes(buffer, sizeof(buffer)); while (n > 0 && !_stop) { ss.sendBytes(buffer, n); n = ss.receiveBytes(buffer, sizeof(buffer)); } } catch (pi::Exception& exc) { std::cerr << "EchoServer: " << exc.displayText() << std::endl; } } } }
void KeyValueStore::handleInsert(StreamSocket& client, const string& buf, Config::ThreadControl& control) { static const char sucResp = Protocol::REQ_SUC; static const char failResp = Protocol::REQ_FAIL; const char* ptr = buf.c_str(); while(*ptr != '\0' && *ptr != '\r' && *ptr != '\n' && *ptr != ' ') ptr++; if(*ptr != ' ') { printKv("Invalid request"); client.sendBytes(&failResp, sizeof(failResp)); return; // Invalid } string key(buf.substr(0, (ptr - buf.c_str()))); string data(buf.substr((ptr - buf.c_str()) + 1)); if(isResponsible(key, control)) { printKv("INSERT request received"); printKv("Received key: "<< key << endl << "Value: "<< data); memDB.insert(key, data); // Respond to client if(data.compare(memDB.lookup(key)) != 0) client.sendBytes(&failResp, sizeof(failResp)); else client.sendBytes(&sucResp, sizeof(sucResp)); KeyValueStore::doReplicate(Protocol::REPL_INS, buf, control); } else { pair<char, string> resp(KeyValueStore::forwardRequest(Protocol::INSERT, buf, control)); client.sendBytes(&resp.first, sizeof(resp.first)); } }
void EchoServer::run() { _ready.set(); Poco::Timespan span(250000); char* pBuffer = new char[_bufferSize]; while (!_stop) { if (_socket.poll(span, Socket::SELECT_READ)) { StreamSocket ss = _socket.acceptConnection(); try { int n = ss.receiveBytes(pBuffer, _bufferSize); while (n > 0 && !_stop) { ss.sendBytes(pBuffer, n); n = ss.receiveBytes(pBuffer, _bufferSize); } } catch (Poco::Exception& exc) { std::cerr << "EchoServer: " << exc.displayText() << std::endl; } } } delete pBuffer; }
void HTTPTestServer::run() { _ready.set(); Poco::Timespan span(250000); while (!_stop) { if (_socket.poll(span, Socket::SELECT_READ)) { StreamSocket ss = _socket.acceptConnection(); try { _lastRequest.clear(); char buffer[256]; int n = ss.receiveBytes(buffer, sizeof(buffer)); while (n > 0 && !_stop) { _lastRequest.append(buffer, n); if (!requestComplete()) n = ss.receiveBytes(buffer, sizeof(buffer)); else n = 0; } std::string response = handleRequest(); ss.sendBytes(response.data(), (int) response.size()); Poco::Thread::sleep(1000); } catch (Poco::Exception& exc) { std::cerr << "HTTPTestServer: " << exc.displayText() << std::endl; } } } }
pair<char, string> KeyValueStore::rcvResponse(StreamSocket& sock, char*& buf) { unsigned contentLength = 0; char resp; pair<char, string> ret; char* msg = NULL; sock.receiveBytes(&resp, sizeof(resp)); if(resp == Protocol::LOOKUP_SUC) { sock.receiveBytes(&contentLength, sizeof(contentLength)); unsigned rem = contentLength; unsigned totalRead = 0; buf = new char[contentLength+1]; msg = buf; buf[contentLength] = '\0'; while((totalRead += sock.receiveBytes(msg, rem)) != contentLength) { msg = buf + totalRead; rem = contentLength - totalRead; } ret = pair<char, string>(resp, buf); delete [] buf; buf = NULL; } else { ret = pair<char, string>(resp, ""); } return ret; }
static ssize_t gnutls_push_wrapper(gnutls_transport_ptr_t session_wrap, const void* buffer, size_t size) { StreamSocket* sock = reinterpret_cast<StreamSocket*>(session_wrap); #ifdef _WIN32 GnuTLSIOHook* session = static_cast<GnuTLSIOHook*>(sock->GetIOHook()); #endif if (sock->GetEventMask() & FD_WRITE_WILL_BLOCK) { #ifdef _WIN32 gnutls_transport_set_errno(session->sess, EAGAIN); #else errno = EAGAIN; #endif return -1; } int rv = SocketEngine::Send(sock, reinterpret_cast<const char *>(buffer), size, 0); #ifdef _WIN32 if (rv < 0) { /* Windows doesn't use errno, but gnutls does, so check SocketEngine::IgnoreError() * and then set errno appropriately. * The gnutls library may also have a different errno variable than us, see * gnutls_transport_set_errno(3). */ gnutls_transport_set_errno(session->sess, SocketEngine::IgnoreError() ? EAGAIN : errno); } #endif if (rv < (int)size) SocketEngine::ChangeEventMask(sock, FD_WRITE_WILL_BLOCK); return rv; }
/** Handling requests */ bool KeyValueStore::handleRequest(StreamSocket& client, Config::ThreadControl& control, char*& buf) { char req; unsigned contentLength = 0; client.receiveBytes(&req, sizeof(req)); if(req == Protocol::EXIT) { return true; } // Always expect that content-length will be the next sent. client.receiveBytes(&contentLength, sizeof(contentLength)); if(contentLength < 0) throw Exception("Invalid content-length detected. Dropping client"); buf = new char[contentLength+1]; buf[contentLength] = '\0'; client.receiveBytes(buf, contentLength); KeyValueStore::handleQuery(client, control, req, buf); delete [] buf; buf = NULL; return false; }
TEST_F(StreamSocketTest, StreamSocketReceiveLineInString) { StreamSocket stream; EXPECT_TRUE(stream.Create(AF_INET)); EXPECT_FALSE(stream.Connect(SocketAddressInet("0.0.0.0:0"))); EXPECT_TRUE(stream.Connect(m_address)) << m_address.ToString(); struct timeval tv; tv.tv_sec = 5; tv.tv_usec = 0; EXPECT_TRUE(stream.WaitWriteable(&tv, true)); std::string sent = "12345\n"; EXPECT_TRUE(stream.SendAll(sent.data(), sent.size())); tv.tv_sec = 5; tv.tv_usec = 0; EXPECT_TRUE(stream.WaitReadable(&tv, true)); std::string received; EXPECT_TRUE(stream.ReceiveLine(&received)); EXPECT_EQ(sent, received); // Send all with timeout tv.tv_sec = 5; tv.tv_usec = 0; size_t sent_size; EXPECT_TRUE(stream.SendAll(sent.data(), sent.size(), &sent_size, &tv)); EXPECT_EQ(sent.size(), sent_size); // peek size with 2 EXPECT_TRUE(stream.ReceiveLine(&received, 2)); EXPECT_EQ(sent, received); }
void TCPServer::run() { while (!_stopped) { Poco::Timespan timeout(250000); if (_socket.poll(timeout, Socket::SELECT_READ)) { try { StreamSocket ss = _socket.acceptConnection(); // enabe nodelay per default: OSX really needs that ss.setNoDelay(true); _pDispatcher->enqueue(ss); } catch (Poco::Exception& exc) { ErrorHandler::handle(exc); } catch (std::exception& exc) { ErrorHandler::handle(exc); } catch (...) { ErrorHandler::handle(); } } } }
void handle(StreamSocket& sock) override { while(true) { cout << "handle called.\n"; string rcvd = sock.receive(); cout << "received data\n"; sock.send_all(rcvd); } }
PartialSendStreamSocket(StreamSocket& stream_socket) : StreamSocket( stream_socket.get_domain(), stream_socket.get_protocol(), static_cast<socket_t>(-1) ), stream_socket(stream_socket.inc_ref()) { }
void LocalSocketTest::testConnect() { SocketAddress sas("/tmp/poco.server.tcp.sock"); ServerSocket serv(sas); StreamSocket ss; Timespan timeout(250000); SocketAddress sac("/tmp/poco.client.tcp.sock"); ss.connect(sas, timeout, &sac); }
void SocketTest::testConnect() { ServerSocket serv; serv.bind(SocketAddress()); serv.listen(); StreamSocket ss; Timespan timeout(250000); ss.connect(SocketAddress("localhost", serv.address().port()), timeout); }
void TCPServer::onReadable(const Socket& socket) { try { StreamSocket ss = _socket.acceptConnection(); // enabe nodelay per default: OSX really needs that ss.setNoDelay(true); clientHandler(ss); } catch(Exception& ex) { WARN("TCPServer socket acceptation: %s",ex.displayText().c_str()); } }
StreamSocket FTPClientSession::establishDataConnection(const std::string& command, const std::string& arg) { StreamSocket ss; if (_passiveMode) ss = passiveDataConnection(command, arg); else ss = activeDataConnection(command, arg); ss.setReceiveTimeout(_timeout); return ss; }
TEST_F(StreamSocketTest, StreamSocketReceiveAll) { StreamSocket stream; EXPECT_TRUE(stream.Create(AF_INET)); EXPECT_TRUE(stream.Connect(m_address)) << m_address.ToString(); std::string sent = "12345\n"; EXPECT_TRUE(stream.SendAll(sent.data(), sent.size())); char buffer1[6], buffer2[5]; size_t buffer1_size = 6; size_t buffer2_size = 5; size_t received_size; EXPECT_TRUE(stream.ReceiveAll(buffer1, buffer1_size)); EXPECT_STREQ(sent.data(), buffer1); // with timeout EXPECT_TRUE(stream.SendAll(sent.data(), sent.size())); struct timeval tv; tv.tv_sec = 5; tv.tv_usec = 0; EXPECT_TRUE(stream.ReceiveAll(buffer1, buffer1_size, &received_size, &tv)); EXPECT_EQ(6U, received_size); EXPECT_STREQ(sent.data(), buffer1); EXPECT_TRUE(stream.SendAll(sent.data(), sent.size())); EXPECT_TRUE(stream.ReceiveAll(buffer2, buffer2_size, &received_size)); EXPECT_EQ(5U, received_size); for (size_t i = 0; i < received_size; ++i) { EXPECT_EQ(sent[i], buffer2[i]); } }
void IoThread() { StreamSocket acceptor; EXPECT_TRUE(m_listener.Accept(&acceptor)); SocketAddressInet peer_address; EXPECT_TRUE(acceptor.GetPeerAddress(&peer_address)); #if __unix__ int keep_alive; int idle; int interval; int count; EXPECT_TRUE(acceptor.SetTcpKeepAliveOption(14400, 150, 5)); EXPECT_TRUE(acceptor.GetOption(SOL_SOCKET, SO_KEEPALIVE, &keep_alive)); EXPECT_EQ(1, keep_alive); EXPECT_TRUE(acceptor.GetOption(SOL_TCP, TCP_KEEPIDLE, &idle)); EXPECT_EQ(14400, idle); EXPECT_TRUE(acceptor.GetOption(SOL_TCP, TCP_KEEPINTVL, &interval)); EXPECT_EQ(150, interval); EXPECT_TRUE(acceptor.GetOption(SOL_TCP, TCP_KEEPCNT, &count)); EXPECT_EQ(5, count); #endif std::string line; while (acceptor.ReceiveLine(&line) && !line.empty()) { acceptor.SendAll(line.data(), line.size()); } }
void SocketTest::testAddress() { ServerSocket serv; serv.bind(SocketAddress()); serv.listen(); StreamSocket ss; ss.connect(SocketAddress("localhost", serv.address().port())); StreamSocket css = serv.acceptConnection(); assert (css.peerAddress().host() == ss.address().host()); assert (css.peerAddress().port() == ss.address().port()); }
static int streamSocketCommandProcess(StreamSocket &ssocket, char *command) { if('\0' == command[0]) //????????? { return 0xff; } StreamPrivatePacket spp; vector<char *> strvec = spp.parse(command, STREAM_PACKET_SPLIT); if(strvec.size() <= 0) { cerr<<"streamSocketCommandProcess strvec.size() <= 0" <<endl; return 0xfe; } int ret = 0; string response; switch(atoi(strvec[0])) { case EN_CMD_ISONLINE: response=strvec[0]; response += ">>"; response += ONLINE; cout << response << endl; //ret = ssocket.send(ssocket.getRemoteSocket(), response); break; case EN_CMD_MEDIA_PLAY: cout << "EN_CMD_MEDIA_PLAY"<< endl; break; case EN_CMD_KEY: cout << "EN_CMD_KEY"<< endl; //deal with key break; case EN_CMD_MUSE: { cout << "EN_CMD_MUSE"<< endl; //deal with mouse } break; case EN_CMD_INPUTSTR: cout << "EN_CMD_INPUTSTR"<< endl; break; default: cout<<"address is" << ssocket.getRemoteIP(); cout<<":" << ssocket.getRemotePort()<< endl; cout <<"command *" <<command << endl; cout<< strvec.size()<<"@ " << strvec[0]<< endl; break; } return ret; }
TEST(Socket, SocketOption) { StreamSocket socket; EXPECT_TRUE(socket.Create(AF_INET)); EXPECT_TRUE(socket.SetCloexec(true)); EXPECT_TRUE(socket.SetLinger(true, 5)); struct linger l; EXPECT_TRUE(socket.GetOption(SOL_SOCKET, SO_LINGER, &l)); EXPECT_TRUE(l.l_onoff); EXPECT_EQ(5, l.l_linger); }
TEST(Socket, Attach) { StreamSocket socket; EXPECT_TRUE(socket.Create(AF_INET)); int handle, old_handle; handle = socket.Handle(); EXPECT_LT(-1, handle); old_handle = socket.Detach(); EXPECT_EQ(handle, old_handle); EXPECT_EQ(-1, socket.Handle()); }
void SocketTest::testFIFOBuffer() { Buffer<char> b(5); b[0] = 'h'; b[1] = 'e'; b[2] = 'l'; b[3] = 'l'; b[4] = 'o'; FIFOBuffer f(5, true); f.readable += delegate(this, &SocketTest::onReadable); f.writable += delegate(this, &SocketTest::onWritable); assert(0 == _notToReadable); assert(0 == _readableToNot); assert(0 == _notToWritable); assert(0 == _writableToNot); f.write(b); assert(1 == _notToReadable); assert(0 == _readableToNot); assert(0 == _notToWritable); assert(1 == _writableToNot); EchoServer echoServer; StreamSocket ss; ss.connect(SocketAddress("localhost", echoServer.port())); int n = ss.sendBytes(f); assert (n == 5); assert(1 == _notToReadable); assert(1 == _readableToNot); assert(1 == _notToWritable); assert(1 == _writableToNot); assert (f.isEmpty()); n = ss.receiveBytes(f); assert (n == 5); assert(2 == _notToReadable); assert(1 == _readableToNot); assert(1 == _notToWritable); assert(2 == _writableToNot); assert (f[0] == 'h'); assert (f[1] == 'e'); assert (f[2] == 'l'); assert (f[3] == 'l'); assert (f[4] == 'o'); f.readable -= delegate(this, &SocketTest::onReadable); f.writable -= delegate(this, &SocketTest::onWritable); ss.close(); }
void LocalSocketTest::testAddress() { SocketAddress sas("/tmp/poco.server.tcp.sock"); ServerSocket serv; serv.bind(sas); serv.listen(); StreamSocket ss; SocketAddress sac("/tmp/poco.client.tcp.sock"); ss.connect(sas, &sac); StreamSocket css = serv.acceptConnection(); assert (css.peerAddress().host() == ss.address().host()); assert (css.peerAddress().port() == ss.address().port()); }
void SocketTest::testEcho() { EchoServer echoServer; StreamSocket ss; ss.connect(SocketAddress("localhost", echoServer.port())); int n = ss.sendBytes("hello", 5); assert (n == 5); char buffer[256]; n = ss.receiveBytes(buffer, sizeof(buffer)); assert (n == 5); assert (std::string(buffer, n) == "hello"); ss.close(); }
//---------------------------------------------------------------------------- int ServerPoll::_OnWrite(ClientContext *pcontext) { StreamSocket streamSocket = pcontext->TheSocket; if (0 == pcontext->SendLen) { BufferEvent *pevent = pcontext->SendQue->PopBufferEvent(); if (!pevent) return 0; int msgid = pevent->GetMessageID(); if (msgid == BufferEvent::MSGID_RESERVED) { pcontext->SendQue->FreeBufferEvent(pevent); return -1; } assert(pevent->mDataLength + MSGLEN_BYTES <= max_sendbuf); // length *(unsigned short *)pcontext->SendBuf = (unsigned short)pevent->mDataLength; memcpy(pcontext->SendBuf + MSGLEN_BYTES, pevent->mBuffer, pevent->mDataLength); // all send length pcontext->SendLen = MSGLEN_BYTES + pevent->mDataLength; pcontext->SendQue->FreeBufferEvent(pevent); } _EnterPendingIO(pcontext); int nbytes = streamSocket.SendBytes(pcontext->SendBuf, pcontext->SendLen, 0); if (nbytes < 0) { _LeavePendingIO(pcontext); return -1; } if (nbytes > 0) { memmove(pcontext->SendBuf, pcontext->SendBuf + nbytes, pcontext->SendLen - nbytes); pcontext->SendLen -= nbytes; assert(pcontext->SendLen >= 0); } _LeavePendingIO(pcontext); return 0; }
void regTest6() { tracef("reg test 6 begin: reg connect timeout."); StreamSocket ss; SocketAddress sa("127.0.0.1", 13333); ss.connect(sa, Timespan(3, 0)); for(int i = 0; i < 25; i++) { tracef("%d seconds...", i + 1); Thread::sleep(1000); } ss.close(); tracef("register test 6 finished."); }
/** Public thread methods (clients connect here) */ void KeyValueStore::PublicThread::run() { Thread threads[MAX_CLIENT_THREADS]; HandleClient threadInst[MAX_CLIENT_THREADS]; const Config::ServerInformation& info = config.getServerInformation(); Config::ThreadControl& control = config.getThreadControl(); int id = 0; char full = Protocol::SRV_FULL; char conn = Protocol::SRV_CONN; ServerSocket server; SocketAddress sock(info.address, info.pubPort); server.bind(sock, true); server.listen(5); printKv("Listening for clients on "<< info.address <<":"<< info.pubPort); while(control.isLive()) { // Simply do thread per client StreamSocket client = server.acceptConnection(); printKv("Received client connection request - waiting for thread to free up"); // Wait five seconds try { freeThreads.wait(5000); // This beats busy waiting } catch(TimeoutException& notUsed(e)) { printKv("Server full - closing connection to client"); client.sendBytes(&full, sizeof(full)); client.close(); continue; } // Send success client.sendBytes(&conn, sizeof(conn)); // tryJoin() doesn't work properly in linux, using isRunning() instead // actively search for the next available thread while(threads[id].isRunning()){ // Try to get an available thread id = (id + 1) % MAX_CLIENT_THREADS; Thread::sleep(250); // 250ms between each check } printKv("Serving client"); threadInst[id] = HandleClient(client, control); threads[id].start(threadInst[id]); } server.close(); freeThreads.set(); // Free a thread with semaphore }