#pragma once #include #include #include #include #include #include namespace DB { /** Работает с готовым Poco::Net::Socket. Операции блокирующие. */ class WriteBufferFromPocoSocket : public BufferWithOwnMemory { protected: Poco::Net::Socket & socket; void nextImpl() { if (!offset()) return; size_t bytes_written = 0; while (bytes_written < offset()) { ssize_t res = 0; /// Добавляем в эксепшены более подробную информацию. try { res = socket.impl()->sendBytes(working_buffer.begin() + bytes_written, offset() - bytes_written); } catch (Poco::Net::NetException & e) { throw Exception(e.displayText() + " while writing to socket (" + socket.peerAddress().toString() + ")", ErrorCodes::NETWORK_ERROR); } catch (Poco::TimeoutException & e) { throw Exception("Timeout exceeded while writing to socket (" + socket.peerAddress().toString() + ")", ErrorCodes::SOCKET_TIMEOUT); } if (res < 0) throw Exception("Cannot write to socket (" + socket.peerAddress().toString() + ")", ErrorCodes::CANNOT_WRITE_TO_SOCKET); bytes_written += res; } } public: WriteBufferFromPocoSocket(Poco::Net::Socket & socket_, size_t buf_size = DBMS_DEFAULT_BUFFER_SIZE) : BufferWithOwnMemory(buf_size), socket(socket_) {} ~WriteBufferFromPocoSocket() { try { next(); } catch (...) { } } }; }