extern "C" { #include } #include #include #include #include #include #include #include #include #include #include #include #include using namespace std::chrono_literals; void SocketHandler::Handle(int sock) { std::cout << std::format("Handler {} start", sock) << std::endl; const int headerSize = 8; std::string rawResHeader; char buffer[headerSize]; memset(&buffer, 0, headerSize); int rsize = 0; if ((rsize = read(sock, &buffer, headerSize)) < 0) { logger.Log("Error read"); close(sock); return; } logger.Log(std::format("rpc rsize {}", rsize)); RPCHeader inRPCHeader; std::string i(buffer, headerSize); inRPCHeader.Decode(i); int rcpPacketSize = inRPCHeader.PacketSize(); logger.Log(std::format("rpc packet size {}", rcpPacketSize)); char buffer2[rcpPacketSize]; if ((rsize = read(sock, &buffer2, rcpPacketSize)) < 0) { logger.Log("Error read"); close(sock); return; } logger.Log(std::format("rpc packet rsize {}", rsize)); std::string rawReq(buffer2, rcpPacketSize); control::HelloRequest pbReq; pbReq.ParseFromString(rawReq); logger.Log(std::format("rpcName: {}", pbReq.meta().rpcname())); logger.Log(std::format("req message: {}\n", pbReq.message())); control::HelloResult pbRes; pbRes.set_message("Johnny!"); auto resMeta = pbRes.mutable_meta(); resMeta->set_error(false); std::string rawRes; pbRes.SerializeToString(&rawRes); RPCHeader outRPCHeader(rawRes.size()); auto rawPacket = outRPCHeader.Encode(); rawPacket.append(rawRes); int wsize = 0; if ((wsize = write(sock, rawPacket.data(), rawPacket.size())) < 0) { logger.Log("Error write"); close(sock); return; } logger.Log(std::format("Handler {} done", sock)); close(sock); } Service::Service(int svcport) { port = svcport; } Service::~Service() { close(port); } std::expected Service::Bind(void) { struct sockaddr_in address; int srvsock; if ((srvsock = socket(AF_INET, SOCK_STREAM, 0)) == 0) { int errnocopy = errno; std::string error = std::strerror(errnocopy); return std::unexpected("Create socker error: " + error); } int opt = 1; if (setsockopt(srvsock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) { int errnocopy = errno; std::string error = std::strerror(errnocopy); return std::unexpected("Set socket option error: " + error); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(port); if (bind(srvsock, (struct sockaddr *)&address, sizeof(address)) < 0) { int errnocopy = errno; std::string error = std::strerror(errnocopy); return std::unexpected("Bind error: " + error); } if (listen(srvsock, 3) < 0) { int errnocopy = errno; std::string error = std::strerror(errnocopy); return std::unexpected("Listen error: " + error); } sock = srvsock; return {}; } std::expected Service::Listen(SocketHandler *handler) { struct sockaddr_in address; int addrlen = sizeof(address); int newsock = 0; for (;;) { if ((newsock = accept(sock, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) { int errnocopy = errno; std::string error = std::strerror(errnocopy); return std::unexpected("Accept error: " + error); } std::jthread t(&SocketHandler::Handle, handler, newsock); t.detach(); } return {}; }