@Override
	void serveBlockStream(Socket socket, BlockStream blockStream) throws IOException {

		if (!(blockStream instanceof OutputBlockStream)) {
			throw new IllegalArgumentException("expected OutputBlockStream");
		}

		socket.setReceiveBufferSize(getPreferredBufferSize());

		OutputBlockStream outputBlockStream = (OutputBlockStream) blockStream;
		try (InputStream in = socket.getInputStream()) {

			copyBlockData(outputBlockStream, in);

			// perform final handshake (uncompressed)

			readStreamEnd(socket, true);

			// Need to close blockStream while client is waiting for final stream end 
			// indicator. This is needed so that the server-based file is fully written 
			// before the client is let loose from the handshake
			outputBlockStream.close();

			writeStreamEnd(socket);
		}
		catch (SocketException e) {
			// remain silent if socket closed by client (e.g., cancelled)
			if (e.getMessage().startsWith("Broken pipe")) {
				throw new EOFException("unexpected end of stream");
			}
			throw e;
		}

	}
<code>ClientInputBlockStream</code> provides the client-side of an
OutputBlockStream which wraps an optionally compressed socket output
stream
Ghidra/Features/GhidraServer/src/main/java/ghidra/server/stream/RemoteOutputBlockStreamHandle.java